1/* Specific flags and argument handling of the C++ front-end.
2   Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING.  If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.  */
20
21#include "config.h"
22#include "system.h"
23
24/* This bit is set if we saw a `-xfoo' language specification.  */
25#define LANGSPEC	(1<<1)
26/* This bit is set if they did `-lm' or `-lmath'.  */
27#define MATHLIB		(1<<2)
28/* This bit is set if they did `-lc'.  */
29#define WITHLIBC	(1<<3)
30
31#ifndef MATH_LIBRARY
32#define MATH_LIBRARY "-lm"
33#endif
34
35#ifndef LIBSTDCXX
36#define LIBSTDCXX "-lstdc++"
37#endif
38
39void
40lang_specific_driver (fn, in_argc, in_argv, in_added_libraries)
41     void (*fn)();
42     int *in_argc;
43     char ***in_argv;
44     int *in_added_libraries;
45{
46  int i, j;
47
48  /* If non-zero, the user gave us the `-v' flag.  */
49  int saw_verbose_flag = 0;
50
51  /* This will be 0 if we encounter a situation where we should not
52     link in libstdc++.  */
53  int library = 1;
54
55  /* The number of arguments being added to what's in argv, other than
56     libraries.  We use this to track the number of times we've inserted
57     -xc++/-xnone.  */
58  int added = 2;
59
60  /* Used to track options that take arguments, so we don't go wrapping
61     those with -xc++/-xnone.  */
62  char *quote = NULL;
63
64  /* The new argument list will be contained in this.  */
65  char **arglist;
66
67  /* Non-zero if we saw a `-xfoo' language specification on the
68     command line.  Used to avoid adding our own -xc++ if the user
69     already gave a language for the file.  */
70  int saw_speclang = 0;
71
72  /* "-lm" or "-lmath" if it appears on the command line.  */
73  char *saw_math = 0;
74
75  /* "-lc" if it appears on the command line.  */
76  char *saw_libc = 0;
77
78  /* An array used to flag each argument that needs a bit set for
79     LANGSPEC, MATHLIB, or WITHLIBC.  */
80  int *args;
81
82  /* By default, we throw on the math library if we have one.  */
83  int need_math = (MATH_LIBRARY[0] != '\0');
84
85  /* The total number of arguments with the new stuff.  */
86  int argc;
87
88  /* The argument list.  */
89  char **argv;
90
91  /* The number of libraries added in.  */
92  int added_libraries;
93
94  /* The total number of arguments with the new stuff.  */
95  int num_args = 1;
96
97  argc = *in_argc;
98  argv = *in_argv;
99  added_libraries = *in_added_libraries;
100
101  args = (int *) xmalloc (argc * sizeof (int));
102  bzero ((char *) args, argc * sizeof (int));
103
104  for (i = 1; i < argc; i++)
105    {
106      /* If the previous option took an argument, we swallow it here.  */
107      if (quote)
108	{
109	  quote = NULL;
110	  continue;
111	}
112
113      /* We don't do this anymore, since we don't get them with minus
114	 signs on them.  */
115      if (argv[i][0] == '\0' || argv[i][1] == '\0')
116	continue;
117
118      if (argv[i][0] == '-')
119	{
120	  if (library != 0 && (strcmp (argv[i], "-nostdlib") == 0
121			       || strcmp (argv[i], "-nodefaultlibs") == 0))
122	    {
123	      library = 0;
124	    }
125	  else if (strcmp (argv[i], "-lm") == 0
126		   || strcmp (argv[i], "-lmath") == 0
127		   || strcmp (argv[i], MATH_LIBRARY) == 0
128#ifdef ALT_LIBM
129		   || strcmp (argv[i], ALT_LIBM) == 0
130#endif
131		  )
132	    {
133	      args[i] |= MATHLIB;
134	      need_math = 0;
135	    }
136	  else if (strcmp (argv[i], "-lc") == 0)
137	    args[i] |= WITHLIBC;
138	  else if (strcmp (argv[i], "-v") == 0)
139	    {
140	      saw_verbose_flag = 1;
141	      if (argc == 2)
142		{
143		  /* If they only gave us `-v', don't try to link
144		     in libg++.  */
145		  library = 0;
146		}
147	    }
148	  else if (strncmp (argv[i], "-x", 2) == 0)
149	    saw_speclang = 1;
150	  else if (((argv[i][2] == '\0'
151		     && (char *)strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL)
152		    || strcmp (argv[i], "-Tdata") == 0))
153	    quote = argv[i];
154	  else if (library != 0 && ((argv[i][2] == '\0'
155		     && (char *) strchr ("cSEM", argv[i][1]) != NULL)
156		    || strcmp (argv[i], "-MM") == 0))
157	    {
158	      /* Don't specify libraries if we won't link, since that would
159		 cause a warning.  */
160	      library = 0;
161	      added -= 2;
162	    }
163	  else
164	    /* Pass other options through.  */
165	    continue;
166	}
167      else
168	{
169	  int len;
170
171	  if (saw_speclang)
172	    {
173	      saw_speclang = 0;
174	      continue;
175	    }
176
177	  /* If the filename ends in .c or .i, put options around it.
178	     But not if a specified -x option is currently active.  */
179	  len = strlen (argv[i]);
180	  if (len > 2
181	      && (argv[i][len - 1] == 'c' || argv[i][len - 1] == 'i')
182	      && argv[i][len - 2] == '.')
183	    {
184	      args[i] |= LANGSPEC;
185	      added += 2;
186	    }
187	}
188    }
189
190  if (quote)
191    (*fn) ("argument to `%s' missing\n", quote);
192
193  /* If we know we don't have to do anything, bail now.  */
194  if (! added && ! library)
195    {
196      free (args);
197      return;
198    }
199
200  num_args = argc + added + need_math;
201  arglist = (char **) xmalloc (num_args * sizeof (char *));
202
203  /* NOTE: We start at 1 now, not 0.  */
204  for (i = 0, j = 0; i < argc; i++, j++)
205    {
206      arglist[j] = argv[i];
207
208      /* Make sure -lstdc++ is before the math library, since libstdc++
209	 itself uses those math routines.  */
210      if (!saw_math && (args[i] & MATHLIB) && library)
211	{
212	  --j;
213	  saw_math = argv[i];
214	}
215
216      if (!saw_libc && (args[i] & WITHLIBC) && library)
217	{
218	  --j;
219	  saw_libc = argv[i];
220	}
221
222      /* Wrap foo.c and foo.i files in a language specification to
223	 force the gcc compiler driver to run cc1plus on them.  */
224      if (args[i] & LANGSPEC)
225	{
226	  int len = strlen (argv[i]);
227	  if (argv[i][len - 1] == 'i')
228	    arglist[j++] = "-xc++-cpp-output";
229	  else
230	    arglist[j++] = "-xc++";
231	  arglist[j++] = argv[i];
232	  arglist[j] = "-xnone";
233	}
234  }
235
236  /* Add `-lstdc++' if we haven't already done so.  */
237  if (library)
238    {
239      arglist[j++] = LIBSTDCXX;
240      added_libraries++;
241    }
242  if (saw_math)
243    arglist[j++] = saw_math;
244  else if (library && need_math)
245    {
246      arglist[j++] = MATH_LIBRARY;
247      added_libraries++;
248    }
249  if (saw_libc)
250    arglist[j++] = saw_libc;
251
252  arglist[j] = NULL;
253
254  *in_argc = j;
255  *in_argv = arglist;
256  *in_added_libraries = added_libraries;
257}
258
259/* Called before linking.  Returns 0 on success and -1 on failure. */
260int lang_specific_pre_link ()  /* Not used for C++. */
261{
262  return 0;
263}
264
265/* Number of extra output files that lang_specific_pre_link may generate. */
266int lang_specific_extra_outfiles = 0;  /* Not used for C++. */
267