/* Compiler driver program that can handle many languages.
- Copyright (C) 1987, 89, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1987, 89, 92-96, 1997 Free Software Foundation, Inc.
This file is part of GNU CC.
When -b is used, the value comes from the `specs' file. */
#ifdef CROSS_COMPILE
-static int cross_compile = 1;
+static char *cross_compile = "1";
#else
-static int cross_compile = 0;
+static char *cross_compile = "0";
#endif
/* The number of errors that have occurred; the link phase will not be
/* Forward declaration for prototypes. */
struct path_prefix;
+static void init_spec PROTO((void));
+static void read_specs PROTO((char *, int));
static void set_spec PROTO((char *, char *));
static struct compiler *lookup_compiler PROTO((char *, int, char *));
static char *build_search_list PROTO((struct path_prefix *, char *, int));
static int is_directory PROTO((char *, char *, int));
static void validate_switches PROTO((char *));
static void validate_all_switches PROTO((void));
-static void give_switch PROTO((int, int));
+static void give_switch PROTO((int, int, int));
static int used_arg PROTO((char *, int));
static int default_arg PROTO((char *, int));
static void set_multilib_dir PROTO((void));
arguments. CC considers `-o foo' as being one switch whose
name starts with `o'. %{o*} would substitute this text,
including the space; thus, two arguments would be generated.
+ %{^S*} likewise, but don't put a blank between a switch and any args.
%{S*:X} substitutes X if one or more switches whose names start with -S are
specified to CC. Note that the tail part of the -S option
(i.e. the part matched by the `*') will be substituted for each
static char *multilib_defaults_raw[] = MULTILIB_DEFAULTS;
-#ifdef EXTRA_SPECS
-static struct { char *name, *spec; } extra_specs[] = { EXTRA_SPECS };
-#endif
-
struct user_specs {
struct user_specs *next;
char *filename;
#endif
}
\f
-/* Read compilation specs from a file named FILENAME,
- replacing the default ones.
-
- A suffix which starts with `*' is a definition for
- one of the machine-specific sub-specs. The "suffix" should be
- *asm, *cc1, *cpp, *link, *startfile, *signed_char, etc.
- The corresponding spec is stored in asm_spec, etc.,
- rather than in the `compilers' vector.
-
- Anything invalid in the file is a fatal error. */
-
-static void
-read_specs (filename)
- char *filename;
-{
- int desc;
- int readlen;
- struct stat statbuf;
- char *buffer;
- register char *p;
-
- if (verbose_flag)
- fprintf (stderr, "Reading specs from %s\n", filename);
-
- /* Open and stat the file. */
- desc = open (filename, O_RDONLY, 0);
- if (desc < 0)
- pfatal_with_name (filename);
- if (stat (filename, &statbuf) < 0)
- pfatal_with_name (filename);
-
- /* Read contents of file into BUFFER. */
- buffer = xmalloc ((unsigned) statbuf.st_size + 1);
- readlen = read (desc, buffer, (unsigned) statbuf.st_size);
- if (readlen < 0)
- pfatal_with_name (filename);
- buffer[readlen] = 0;
- close (desc);
-
- /* Scan BUFFER for specs, putting them in the vector. */
- p = buffer;
- while (1)
- {
- char *suffix;
- char *spec;
- char *in, *out, *p1, *p2;
-
- /* Advance P in BUFFER to the next nonblank nocomment line. */
- p = skip_whitespace (p);
- if (*p == 0)
- break;
-
- /* Find the colon that should end the suffix. */
- p1 = p;
- while (*p1 && *p1 != ':' && *p1 != '\n') p1++;
- /* The colon shouldn't be missing. */
- if (*p1 != ':')
- fatal ("specs file malformed after %d characters", p1 - buffer);
- /* Skip back over trailing whitespace. */
- p2 = p1;
- while (p2 > buffer && (p2[-1] == ' ' || p2[-1] == '\t')) p2--;
- /* Copy the suffix to a string. */
- suffix = save_string (p, p2 - p);
- /* Find the next line. */
- p = skip_whitespace (p1 + 1);
- if (p[1] == 0)
- fatal ("specs file malformed after %d characters", p - buffer);
- p1 = p;
- /* Find next blank line. */
- while (*p1 && !(*p1 == '\n' && p1[1] == '\n')) p1++;
- /* Specs end at the blank line and do not include the newline. */
- spec = save_string (p, p1 - p);
- p = p1;
-
- /* Delete backslash-newline sequences from the spec. */
- in = spec;
- out = spec;
- while (*in != 0)
- {
- if (in[0] == '\\' && in[1] == '\n')
- in += 2;
- else if (in[0] == '#')
- {
- while (*in && *in != '\n') in++;
- }
- else
- *out++ = *in++;
- }
- *out = 0;
-
- if (suffix[0] == '*')
- {
- if (! strcmp (suffix, "*link_command"))
- link_command_spec = spec;
- else
- set_spec (suffix + 1, spec);
- }
- else
- {
- /* Add this pair to the vector. */
- compilers
- = ((struct compiler *)
- xrealloc (compilers, (n_compilers + 2) * sizeof (struct compiler)));
- compilers[n_compilers].suffix = suffix;
- bzero ((char *) compilers[n_compilers].spec,
- sizeof compilers[n_compilers].spec);
- compilers[n_compilers].spec[0] = spec;
- n_compilers++;
- bzero ((char *) &compilers[n_compilers],
- sizeof compilers[n_compilers]);
- }
-
- if (*suffix == 0)
- link_command_spec = spec;
- }
-
- if (link_command_spec == 0)
- fatal ("spec file has no spec for linking");
-}
-
static char *
skip_whitespace (p)
char *p;
struct spec_list
{
- char *name; /* Name of the spec. */
- char *spec; /* The spec itself. */
- struct spec_list *next; /* Next spec in linked list. */
+ /* The following 2 fields must be first */
+ /* to allow EXTRA_SPECS to be initialized */
+ char *name; /* name of the spec. */
+ char *ptr; /* available ptr if no static pointer */
+
+ /* The following fields are not initialized */
+ /* by EXTRA_SPECS */
+ char **ptr_spec; /* pointer to the spec itself. */
+ struct spec_list *next; /* Next spec in linked list. */
+ int name_len; /* length of the name */
+ int alloc_p; /* whether string was allocated */
};
-/* List of specs that have been defined so far. */
+#define INIT_STATIC_SPEC(NAME,PTR) \
+{ NAME, NULL_PTR, PTR, (struct spec_list *)0, sizeof (NAME)-1, 0 }
+
+/* List of statically defined specs */
+static struct spec_list static_specs[] = {
+ INIT_STATIC_SPEC ("asm", &asm_spec),
+ INIT_STATIC_SPEC ("asm_final", &asm_final_spec),
+ INIT_STATIC_SPEC ("cpp", &cpp_spec),
+ INIT_STATIC_SPEC ("cc1", &cc1_spec),
+ INIT_STATIC_SPEC ("cc1plus", &cc1plus_spec),
+ INIT_STATIC_SPEC ("endfile", &endfile_spec),
+ INIT_STATIC_SPEC ("link", &link_spec),
+ INIT_STATIC_SPEC ("lib", &lib_spec),
+ INIT_STATIC_SPEC ("libgcc", &libgcc_spec),
+ INIT_STATIC_SPEC ("startfile", &startfile_spec),
+ INIT_STATIC_SPEC ("switches_need_spaces", &switches_need_spaces),
+ INIT_STATIC_SPEC ("signed_char", &signed_char_spec),
+ INIT_STATIC_SPEC ("predefines", &cpp_predefines),
+ INIT_STATIC_SPEC ("cross_compile", &cross_compile),
+ INIT_STATIC_SPEC ("version", &compiler_version),
+ INIT_STATIC_SPEC ("multilib", &multilib_select),
+ INIT_STATIC_SPEC ("multilib_defaults", &multilib_defaults),
+ INIT_STATIC_SPEC ("multilib_extra", &multilib_extra),
+ INIT_STATIC_SPEC ("multilib_matches", &multilib_matches),
+};
+
+#ifdef EXTRA_SPECS /* additional specs needed */
+static struct spec_list extra_specs[] = { EXTRA_SPECS };
+#endif
+
+/* List of dynamically allocates specs that have been defined so far. */
+
+static struct spec_list *specs = (struct spec_list *)0;
+
+\f
+/* Initialize the specs lookup routines. */
+
+static void
+init_spec ()
+{
+ struct spec_list *next = (struct spec_list *)0;
+ struct spec_list *sl = (struct spec_list *)0;
+ int i;
+
+ if (specs)
+ return; /* already initialized */
+
+ if (verbose_flag)
+ fprintf (stderr, "Using builtin specs.\n");
+
+#ifdef EXTRA_SPECS
+ for (i = (sizeof (extra_specs) / sizeof (extra_specs[0])) - 1; i >= 0; i--)
+ {
+ sl = &extra_specs[i];
+ sl->next = next;
+ sl->name_len = strlen (sl->name);
+ sl->ptr_spec = &sl->ptr;
+ next = sl;
+ }
+#endif
+
+ for (i = (sizeof (static_specs) / sizeof (static_specs[0])) - 1; i >= 0; i--)
+ {
+ sl = &static_specs[i];
+ sl->next = next;
+ next = sl;
+ }
+
+ specs = sl;
+}
-static struct spec_list *specs = (struct spec_list *) 0;
\f
/* Change the value of spec NAME to SPEC. If SPEC is empty, then the spec is
removed; If the spec starts with a + then SPEC is added to the end of the
{
struct spec_list *sl;
char *old_spec;
+ int name_len = strlen (name);
+ int i;
+
+ /* If this is the first call, initialize the statically allocated specs */
+ if (!specs)
+ {
+ struct spec_list *next = (struct spec_list *)0;
+ for (i = (sizeof (static_specs) / sizeof (static_specs[0])) - 1; i >= 0; i--)
+ {
+ sl = &static_specs[i];
+ sl->next = next;
+ next = sl;
+ }
+ specs = sl;
+ }
/* See if the spec already exists */
for (sl = specs; sl; sl = sl->next)
- if (strcmp (sl->name, name) == 0)
+ if (name_len == sl->name_len && !strcmp (sl->name, name))
break;
if (!sl)
/* Not found - make it */
sl = (struct spec_list *) xmalloc (sizeof (struct spec_list));
sl->name = save_string (name, strlen (name));
- sl->spec = save_string ("", 0);
+ sl->name_len = name_len;
+ sl->ptr_spec = &sl->ptr;
+ sl->alloc_p = 0;
+ *(sl->ptr_spec) = "";
sl->next = specs;
specs = sl;
}
- old_spec = sl->spec;
- if (name && spec[0] == '+' && isspace (spec[1]))
- sl->spec = concat (old_spec, spec + 1, NULL_PTR);
- else
- sl->spec = save_string (spec, strlen (spec));
-
- if (! strcmp (name, "asm"))
- asm_spec = sl->spec;
- else if (! strcmp (name, "asm_final"))
- asm_final_spec = sl->spec;
- else if (! strcmp (name, "cc1"))
- cc1_spec = sl->spec;
- else if (! strcmp (name, "cc1plus"))
- cc1plus_spec = sl->spec;
- else if (! strcmp (name, "cpp"))
- cpp_spec = sl->spec;
- else if (! strcmp (name, "endfile"))
- endfile_spec = sl->spec;
- else if (! strcmp (name, "lib"))
- lib_spec = sl->spec;
- else if (! strcmp (name, "libgcc"))
- libgcc_spec = sl->spec;
- else if (! strcmp (name, "link"))
- link_spec = sl->spec;
- else if (! strcmp (name, "predefines"))
- cpp_predefines = sl->spec;
- else if (! strcmp (name, "signed_char"))
- signed_char_spec = sl->spec;
- else if (! strcmp (name, "startfile"))
- startfile_spec = sl->spec;
- else if (! strcmp (name, "switches_need_spaces"))
- switches_need_spaces = sl->spec;
- else if (! strcmp (name, "cross_compile"))
- cross_compile = atoi (sl->spec);
- else if (! strcmp (name, "multilib"))
- multilib_select = sl->spec;
- else if (! strcmp (name, "multilib_matches"))
- multilib_matches = sl->spec;
- else if (! strcmp (name, "multilib_extra"))
- multilib_extra = sl->spec;
- else if (! strcmp (name, "multilib_defaults"))
- multilib_defaults = sl->spec;
- else if (! strcmp (name, "version"))
- compiler_version = sl->spec;
-#ifdef EXTRA_SPECS
- else
- {
- int i;
- for (i = 0; i < sizeof (extra_specs) / sizeof (extra_specs[0]); i++)
- {
- if (! strcmp (name, extra_specs[i].name))
- {
- extra_specs[i].spec = sl->spec;
- break;
- }
- }
- }
+ old_spec = *(sl->ptr_spec);
+ *(sl->ptr_spec) = ((spec[0] == '+' && isspace (spec[1]))
+ ? concat (old_spec, spec + 1, NULL_PTR)
+ : save_string (spec, strlen (spec)));
+
+#ifdef DEBUG_SPECS
+ if (verbose_flag)
+ fprintf (stderr, "Setting spec %s to '%s'\n\n", name, *(sl->ptr_spec));
#endif
/* Free the old spec */
- if (old_spec)
+ if (old_spec && sl->alloc_p)
free (old_spec);
+
+ sl->alloc_p = 1;
}
\f
/* Accumulate a command (program name and args), and run it. */
record_temp_file (arg, delete_always, delete_failure);
}
\f
+/* Read compilation specs from a file named FILENAME,
+ replacing the default ones.
+
+ A suffix which starts with `*' is a definition for
+ one of the machine-specific sub-specs. The "suffix" should be
+ *asm, *cc1, *cpp, *link, *startfile, *signed_char, etc.
+ The corresponding spec is stored in asm_spec, etc.,
+ rather than in the `compilers' vector.
+
+ Anything invalid in the file is a fatal error. */
+
+static void
+read_specs (filename, main_p)
+ char *filename;
+ int main_p;
+{
+ int desc;
+ int readlen;
+ struct stat statbuf;
+ char *buffer;
+ register char *p;
+
+ if (verbose_flag)
+ fprintf (stderr, "Reading specs from %s\n", filename);
+
+ /* Open and stat the file. */
+ desc = open (filename, O_RDONLY, 0);
+ if (desc < 0)
+ pfatal_with_name (filename);
+ if (stat (filename, &statbuf) < 0)
+ pfatal_with_name (filename);
+
+ /* Read contents of file into BUFFER. */
+ buffer = xmalloc ((unsigned) statbuf.st_size + 1);
+ readlen = read (desc, buffer, (unsigned) statbuf.st_size);
+ if (readlen < 0)
+ pfatal_with_name (filename);
+ buffer[readlen] = 0;
+ close (desc);
+
+ /* Scan BUFFER for specs, putting them in the vector. */
+ p = buffer;
+ while (1)
+ {
+ char *suffix;
+ char *spec;
+ char *in, *out, *p1, *p2, *p3;
+
+ /* Advance P in BUFFER to the next nonblank nocomment line. */
+ p = skip_whitespace (p);
+ if (*p == 0)
+ break;
+
+ /* Is this a special command that starts with '%'? */
+ /* Don't allow this for the main specs file, since it would
+ encourage people to overwrite it. */
+ if (*p == '%' && !main_p)
+ {
+ p1 = p;
+ while (*p && *p != '\n') p++;
+ p++; /* skip \n */
+
+ if (!strncmp (p1, "%include", sizeof ("%include")-1)
+ && (p1[ sizeof ("%include")-1 ] == ' '
+ || p1[ sizeof ("%include")-1 ] == '\t'))
+ {
+ char *new_filename;
+
+ p1 += sizeof ("%include");
+ while (*p1 == ' ' || *p1 == '\t') p1++;
+
+ if (*p1++ != '<' || p[-2] != '>')
+ fatal ("specs %%include syntax malformed after %d characters",
+ p1 - buffer + 1);
+
+ p[-2] = '\0';
+ new_filename = find_a_file (&startfile_prefixes, p1, R_OK);
+ read_specs (new_filename ? new_filename : p1, FALSE);
+ continue;
+ }
+ else if (!strncmp (p1, "%include_noerr", sizeof ("%include_noerr")-1)
+ && (p1[ sizeof ("%include_noerr")-1 ] == ' '
+ || p1[ sizeof ("%include_noerr")-1 ] == '\t'))
+ {
+ char *new_filename;
+
+ p1 += sizeof ("%include_noerr");
+ while (*p1 == ' ' || *p1 == '\t') p1++;
+
+ if (*p1++ != '<' || p[-2] != '>')
+ fatal ("specs %%include syntax malformed after %d characters",
+ p1 - buffer + 1);
+
+ p[-2] = '\0';
+ new_filename = find_a_file (&startfile_prefixes, p1, R_OK);
+ if (new_filename)
+ read_specs (new_filename, FALSE);
+ else if (verbose_flag)
+ fprintf (stderr, "Could not find specs file %s\n", p1);
+ continue;
+ }
+ else if (!strncmp (p1, "%rename", sizeof ("%rename")-1)
+ && (p1[ sizeof ("%rename")-1 ] == ' '
+ || p1[ sizeof ("%rename")-1 ] == '\t'))
+ {
+ int name_len;
+ struct spec_list *sl;
+
+ /* Get original name */
+ p1 += sizeof ("%rename");
+ while (*p1 == ' ' || *p1 == '\t') p1++;
+ if (!isalpha (*p1))
+ fatal ("specs %%rename syntax malformed after %d characters",
+ p1 - buffer);
+
+ p2 = p1;
+ while (*p2 && !isspace (*p2)) p2++;
+ if (*p2 != ' ' && *p2 != '\t')
+ fatal ("specs %%rename syntax malformed after %d characters",
+ p2 - buffer);
+
+ name_len = p2 - p1;
+ *p2++ = '\0';
+ while (*p2 == ' ' || *p2 == '\t') p2++;
+ if (!isalpha (*p2))
+ fatal ("specs %%rename syntax malformed after %d characters",
+ p2 - buffer);
+
+ /* Get new spec name */
+ p3 = p2;
+ while (*p3 && !isspace (*p3)) p3++;
+ if (p3 != p-1)
+ fatal ("specs %%rename syntax malformed after %d characters",
+ p3 - buffer);
+ *p3 = '\0';
+
+ for (sl = specs; sl; sl = sl->next)
+ if (name_len == sl->name_len && !strcmp (sl->name, p1))
+ break;
+
+ if (!sl)
+ fatal ("specs %s spec was not found to be renamed", p1);
+
+ if (!strcmp (p1, p2))
+ continue;
+
+ if (verbose_flag)
+ {
+ fprintf (stderr, "rename spec %s to %s\n", p1, p2);
+#ifdef DEBUG_SPECS
+ fprintf (stderr, "spec is '%s'\n\n", *(sl->ptr_spec));
+#endif
+ }
+
+ set_spec (p2, *(sl->ptr_spec));
+ if (sl->alloc_p)
+ free (*(sl->ptr_spec));
+
+ *(sl->ptr_spec) = "";
+ sl->alloc_p = 0;
+ continue;
+ }
+ else
+ fatal ("specs unknown %% command after %d characters",
+ p1 - buffer);
+ }
+
+ /* Find the colon that should end the suffix. */
+ p1 = p;
+ while (*p1 && *p1 != ':' && *p1 != '\n') p1++;
+ /* The colon shouldn't be missing. */
+ if (*p1 != ':')
+ fatal ("specs file malformed after %d characters", p1 - buffer);
+ /* Skip back over trailing whitespace. */
+ p2 = p1;
+ while (p2 > buffer && (p2[-1] == ' ' || p2[-1] == '\t')) p2--;
+ /* Copy the suffix to a string. */
+ suffix = save_string (p, p2 - p);
+ /* Find the next line. */
+ p = skip_whitespace (p1 + 1);
+ if (p[1] == 0)
+ fatal ("specs file malformed after %d characters", p - buffer);
+ p1 = p;
+ /* Find next blank line. */
+ while (*p1 && !(*p1 == '\n' && p1[1] == '\n')) p1++;
+ /* Specs end at the blank line and do not include the newline. */
+ spec = save_string (p, p1 - p);
+ p = p1;
+
+ /* Delete backslash-newline sequences from the spec. */
+ in = spec;
+ out = spec;
+ while (*in != 0)
+ {
+ if (in[0] == '\\' && in[1] == '\n')
+ in += 2;
+ else if (in[0] == '#')
+ {
+ while (*in && *in != '\n') in++;
+ }
+ else
+ *out++ = *in++;
+ }
+ *out = 0;
+
+ if (suffix[0] == '*')
+ {
+ if (! strcmp (suffix, "*link_command"))
+ link_command_spec = spec;
+ else
+ set_spec (suffix + 1, spec);
+ }
+ else
+ {
+ /* Add this pair to the vector. */
+ compilers
+ = ((struct compiler *)
+ xrealloc (compilers, (n_compilers + 2) * sizeof (struct compiler)));
+ compilers[n_compilers].suffix = suffix;
+ bzero ((char *) compilers[n_compilers].spec,
+ sizeof compilers[n_compilers].spec);
+ compilers[n_compilers].spec[0] = spec;
+ n_compilers++;
+ bzero ((char *) &compilers[n_compilers],
+ sizeof compilers[n_compilers]);
+ }
+
+ if (*suffix == 0)
+ link_command_spec = spec;
+ }
+
+ if (link_command_spec == 0)
+ fatal ("spec file has no spec for linking");
+}
+\f
/* Record the names of temporary files we tell compilers to write,
and delete them at the end of the run. */
}
temp = getenv ("LIBRARY_PATH");
- if (temp && ! cross_compile)
+ if (temp && *cross_compile == '0')
{
char *startp, *endp;
char *nstore = (char *) alloca (strlen (temp) + 3);
/* Use LPATH like LIBRARY_PATH (for the CMU build program). */
temp = getenv ("LPATH");
- if (temp && ! cross_compile)
+ if (temp && *cross_compile == '0')
{
char *startp, *endp;
char *nstore = (char *) alloca (strlen (temp) + 3);
{
if (! strcmp (argv[i], "-dumpspecs"))
{
- printf ("*asm:\n%s\n\n", asm_spec);
- printf ("*asm_final:\n%s\n\n", asm_final_spec);
- printf ("*cpp:\n%s\n\n", cpp_spec);
- printf ("*cc1:\n%s\n\n", cc1_spec);
- printf ("*cc1plus:\n%s\n\n", cc1plus_spec);
- printf ("*endfile:\n%s\n\n", endfile_spec);
- printf ("*link:\n%s\n\n", link_spec);
- printf ("*lib:\n%s\n\n", lib_spec);
- printf ("*libgcc:\n%s\n\n", libgcc_spec);
- printf ("*startfile:\n%s\n\n", startfile_spec);
- printf ("*switches_need_spaces:\n%s\n\n", switches_need_spaces);
- printf ("*signed_char:\n%s\n\n", signed_char_spec);
- printf ("*predefines:\n%s\n\n", cpp_predefines);
- printf ("*cross_compile:\n%d\n\n", cross_compile);
- printf ("*version:\n%s\n\n", compiler_version);
- printf ("*multilib:\n%s\n\n", multilib_select);
- printf ("*multilib_defaults:\n%s\n\n", multilib_defaults);
- printf ("*multilib_extra:\n%s\n\n", multilib_extra);
- printf ("*multilib_matches:\n%s\n\n", multilib_matches);
-
-#ifdef EXTRA_SPECS
- {
- int j;
- for (j = 0; j < sizeof (extra_specs) / sizeof (extra_specs[0]); j++)
- printf ("*%s:\n%s\n\n", extra_specs[j].name,
- (extra_specs[j].spec) ? extra_specs[j].spec : "");
- }
-#endif
+ struct spec_list *sl;
+ init_spec ();
+ for (sl = specs; sl; sl = sl->next)
+ printf ("*%s:\n%s\n\n", sl->name, *(sl->ptr_spec));
exit (0);
}
else if (! strcmp (argv[i], "-dumpversion"))
{
char *string = xmalloc (len + 1);
strncpy (string, value, len-7);
- strcat (string, "include");
+ strcpy (string+len-7, "include");
add_prefix (&include_prefixes, string,
1, 0, NULL_PTR);
}
/* See if it's in the list */
for (len = p - name, sl = specs; sl; sl = sl->next)
- if (strncmp (sl->name, name, len) == 0 && !sl->name[len])
+ if (sl->name_len == len && !strncmp (sl->name, name, len))
{
- name = sl->spec;
+ name = *(sl->ptr_spec);
+#ifdef DEBUG_SPECS
+ fprintf (stderr, "Processing spec %c%s%c, which is '%s'\n",
+ c, sl->name, (c == '(') ? ')' : ']', name);
+#endif
break;
}
int pipe_p = 0;
int negate = 0;
int suffix = 0;
+ int include_blanks = 1;
+
+ if (*p == '^')
+ /* A '^' after the open-brace means to not give blanks before args. */
+ include_blanks = 0, ++p;
if (*p == '|')
/* A `|' after the open-brace means,
for (i = 0; i < n_switches; i++)
if (!strncmp (switches[i].part1, filter, p - filter)
&& check_live_switch (i, p - filter))
- give_switch (i, 0);
+ give_switch (i, 0, include_blanks);
}
else
{
{
do_spec_1 (string, 0, &switches[i].part1[hard_match_len]);
/* Pass any arguments this switch has. */
- give_switch (i, 1);
+ give_switch (i, 1, 1);
}
return q;
{
if (*p == '}')
{
- give_switch (i, 0);
+ give_switch (i, 0, include_blanks);
}
else
{
the vector of switches gcc received, which is `switches'.
This cannot fail since it never finishes a command line.
- If OMIT_FIRST_WORD is nonzero, then we omit .part1 of the argument. */
+ If OMIT_FIRST_WORD is nonzero, then we omit .part1 of the argument.
+
+ If INCLUDE_BLANKS is nonzero, then we include blanks before each argument
+ of the switch. */
static void
-give_switch (switchnum, omit_first_word)
+give_switch (switchnum, omit_first_word, include_blanks)
int switchnum;
int omit_first_word;
+ int include_blanks;
{
if (!omit_first_word)
{
do_spec_1 ("-", 0, NULL_PTR);
do_spec_1 (switches[switchnum].part1, 1, NULL_PTR);
}
- do_spec_1 (" ", 0, NULL_PTR);
+
if (switches[switchnum].args != 0)
{
char **p;
for (p = switches[switchnum].args; *p; p++)
{
+ if (include_blanks)
+ do_spec_1 (" ", 0, NULL_PTR);
do_spec_1 (*p, 1, NULL_PTR);
- do_spec_1 (" ", 0, NULL_PTR);
}
}
+
+ do_spec_1 (" ", 0, NULL_PTR);
switches[switchnum].valid = 1;
}
\f
specs_file = find_a_file (&startfile_prefixes, "specs", R_OK);
/* Read the specs file unless it is a default one. */
if (specs_file != 0 && strcmp (specs_file, "specs"))
- read_specs (specs_file);
-
-#ifdef EXTRA_SPECS
+ read_specs (specs_file, TRUE);
else
- {
- int k;
- for (k = 0; k < sizeof (extra_specs) / sizeof (extra_specs[0]); k++)
- set_spec (extra_specs[k].name, extra_specs[k].spec);
- }
-#endif
-
+ init_spec ();
+
+ /* We need to check standard_exec_prefix/just_machine_suffix/specs
+ for any override of as, ld and libraries. */
+ specs_file = (char *) alloca (strlen (standard_exec_prefix)
+ + strlen (just_machine_suffix)
+ + sizeof ("specs"));
+
+ strcpy (specs_file, standard_exec_prefix);
+ strcat (specs_file, just_machine_suffix);
+ strcat (specs_file, "specs");
+ if (access (specs_file, R_OK) == 0)
+ read_specs (specs_file, TRUE);
+
/* Process any user specified specs in the order given on the command
line. */
for (uptr = user_specs_head; uptr; uptr = uptr->next)
{
char *filename = find_a_file (&startfile_prefixes, uptr->filename, R_OK);
- read_specs (filename ? filename : uptr->filename);
+ read_specs (filename ? filename : uptr->filename, FALSE);
}
/* If not cross-compiling, look for startfiles in the standard places. */
/* The fact that these are done here, after reading the specs file,
means that it cannot be found in these directories.
But that's okay. It should never be there anyway. */
- if (!cross_compile)
+ if (*cross_compile == '0')
{
#ifdef MD_EXEC_PREFIX
add_prefix (&exec_prefixes, md_exec_prefix, 0, 0, NULL_PTR);
}
}
- /* look through the linked list of extra specs read from the specs file */
+ /* look through the linked list of specs read from the specs file */
for (spec = specs; spec ; spec = spec->next)
{
- p = spec->spec;
+ p = *(spec->ptr_spec);
while (c = *p++)
if (c == '%' && *p == '{')
/* We have a switch spec. */
if (c == '%' && *p == '{')
/* We have a switch spec. */
validate_switches (p + 1);
-
- /* Now notice switches mentioned in the machine-specific specs. */
-
- p = asm_spec;
- while (c = *p++)
- if (c == '%' && *p == '{')
- /* We have a switch spec. */
- validate_switches (p + 1);
-
- p = asm_final_spec;
- while (c = *p++)
- if (c == '%' && *p == '{')
- /* We have a switch spec. */
- validate_switches (p + 1);
-
- p = cpp_spec;
- while (c = *p++)
- if (c == '%' && *p == '{')
- /* We have a switch spec. */
- validate_switches (p + 1);
-
- p = signed_char_spec;
- while (c = *p++)
- if (c == '%' && *p == '{')
- /* We have a switch spec. */
- validate_switches (p + 1);
-
- p = cc1_spec;
- while (c = *p++)
- if (c == '%' && *p == '{')
- /* We have a switch spec. */
- validate_switches (p + 1);
-
- p = cc1plus_spec;
- while (c = *p++)
- if (c == '%' && *p == '{')
- /* We have a switch spec. */
- validate_switches (p + 1);
-
- p = link_spec;
- while (c = *p++)
- if (c == '%' && *p == '{')
- /* We have a switch spec. */
- validate_switches (p + 1);
-
- p = lib_spec;
- while (c = *p++)
- if (c == '%' && *p == '{')
- /* We have a switch spec. */
- validate_switches (p + 1);
-
- p = libgcc_spec;
- while (c = *p++)
- if (c == '%' && *p == '{')
- /* We have a switch spec. */
- validate_switches (p + 1);
-
- p = startfile_spec;
- while (c = *p++)
- if (c == '%' && *p == '{')
- /* We have a switch spec. */
- validate_switches (p + 1);
-
-#ifdef EXTRA_SPECS
- {
- int i;
- for (i = 0; i < sizeof (extra_specs) / sizeof (extra_specs[0]); i++)
- {
- p = extra_specs[i].spec;
- while (c = *p++)
- if (c == '%' && *p == '{')
- /* We have a switch spec. */
- validate_switches (p + 1);
- }
- }
-#endif
-
}
/* Look at the switch-name that comes after START