#define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
#endif
+#ifdef VMS
+#define exit __posix_exit
+#endif
+
/* Define O_RDONLY if the system hasn't defined it for us. */
#ifndef O_RDONLY
#define O_RDONLY 0
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 struct { char *name, *spec; } extra_specs[] = { EXTRA_SPECS };
#endif
+struct user_specs {
+ struct user_specs *next;
+ char *filename;
+};
+
+static struct user_specs *user_specs_head, *user_specs_tail;
+
/* This defines which switch letters take arguments. */
#define DEFAULT_SWITCH_TAKES_ARG(CHAR) \
|| !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \
|| !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \
|| !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \
- || !strcmp (STR, "isystem"))
+ || !strcmp (STR, "isystem") || !strcmp (STR, "specs"))
#ifndef WORD_SWITCH_TAKES_ARG
#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
{"--comments", "-C", 0},
{"--compile", "-c", 0},
{"--debug", "-g", "oj"},
- {"--define-macro", "-D", "a"},
+ {"--define-macro", "-D", "aj"},
{"--dependencies", "-M", 0},
{"--dump", "-d", "a"},
{"--dumpbase", "-dumpbase", "a"},
{"--imacros", "-imacros", "a"},
{"--include", "-include", "a"},
{"--include-barrier", "-I-", 0},
- {"--include-directory", "-I", "a"},
+ {"--include-directory", "-I", "aj"},
{"--include-directory-after", "-idirafter", "a"},
{"--include-prefix", "-iprefix", "a"},
{"--include-with-prefix", "-iwithprefix", "a"},
{"--save-temps", "-save-temps", 0},
{"--shared", "-shared", 0},
{"--silent", "-q", 0},
+ {"--specs", "-specs=", "aj"},
{"--static", "-static", 0},
{"--symbolic", "-symbolic", 0},
{"--target", "-b", "a"},
{"--traditional", "-traditional", 0},
{"--traditional-cpp", "-traditional-cpp", 0},
{"--trigraphs", "-trigraphs", 0},
- {"--undefine-macro", "-U", "a"},
+ {"--undefine-macro", "-U", "aj"},
{"--use-version", "-V", "a"},
{"--user-dependencies", "-MM", 0},
{"--verbose", "-v", 0},
/* Convert new-style -- options to old-style. */
translate_options (&argc, &argv);
+#ifdef LANG_SPECIFIC_DRIVER
+ /* Do language-specific adjustment/addition of flags. */
+ lang_specific_driver (&fatal, &argc, &argv);
+#endif
+
/* Scan argv twice. Here, the first time, just count how many switches
there will be in their vector, and how many input files in theirs.
Here we also parse the switches that cc itself uses (e.g. -v). */
save_temps_flag = 1;
n_switches++;
}
+ else if (strcmp (argv[i], "-specs") == 0)
+ {
+ struct user_specs *user = (struct user_specs *)
+ xmalloc (sizeof (struct user_specs));
+ if (++i >= argc)
+ fatal ("argument to `-specs' is missing");
+
+ user->next = (struct user_specs *)0;
+ user->filename = argv[i];
+ if (user_specs_tail)
+ user_specs_tail->next = user;
+ else
+ user_specs_head = user;
+ user_specs_tail = user;
+ }
+ else if (strncmp (argv[i], "-specs=", 7) == 0)
+ {
+ struct user_specs *user = (struct user_specs *)
+ xmalloc (sizeof (struct user_specs));
+ if (strlen (argv[i]) == 7)
+ fatal ("argument to `-specs=' is missing");
+
+ user->next = (struct user_specs *)0;
+ user->filename = argv[i]+7;
+ if (user_specs_tail)
+ user_specs_tail->next = user;
+ else
+ user_specs_head = user;
+ user_specs_tail = user;
+ }
else if (argv[i][0] == '-' && argv[i][1] != 0)
{
register char *p = &argv[i][1];
infiles[n_infiles].language = 0;
infiles[n_infiles++].name = argv[i];
}
+ else if (strcmp (argv[i], "-specs") == 0)
+ i++;
+ else if (strncmp (argv[i], "-specs=", 7) == 0)
+ ;
else if (argv[i][0] == '-' && argv[i][1] != 0)
{
register char *p = &argv[i][1];
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
char *explicit_link_files;
char *specs_file;
char *p;
+ struct user_specs *uptr;
p = argv[0] + strlen (argv[0]);
while (p != argv[0] && p[-1] != '/' && p[-1] != DIR_SEPARATOR) --p;
}
#endif
+ /* 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);
+ }
+
/* 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.