OSDN Git Service

merge
[pf3gnuchains/gcc-fork.git] / gcc / cp / g++spec.c
1 #include "config.h"
2
3 #include <sys/types.h>
4 #include <stdio.h>
5
6 #include "gansidecl.h"
7
8 /* This bit is set if we saw a `-xfoo' language specification.  */
9 #define LANGSPEC        (1<<1)
10 /* This bit is set if they did `-lm' or `-lmath'.  */
11 #define MATHLIB         (1<<2)
12 /* This bit is set if they did `-lc'.  */
13 #define WITHLIBC        (1<<3)
14
15 #ifndef MATH_LIBRARY
16 #define MATH_LIBRARY "-lm"
17 #endif
18
19 extern char *xmalloc PROTO((size_t));
20
21 void
22 lang_specific_driver (fn, in_argc, in_argv)
23      void (*fn)();
24      int *in_argc;
25      char ***in_argv;
26 {
27   int i, j;
28
29   /* If non-zero, the user gave us the `-v' flag.  */ 
30   int saw_verbose_flag = 0;
31
32   /* This will be 0 if we encounter a situation where we should not
33      link in libstdc++.  */
34   int library = 1;
35
36   /* The number of arguments being added to what's in argv, other than
37      libraries.  We use this to track the number of times we've inserted
38      -xc++/-xnone.  */
39   int added = 2;
40
41   /* Used to track options that take arguments, so we don't go wrapping
42      those with -xc++/-xnone.  */
43   char *quote = NULL;
44
45   /* The new argument list will be contained in this.  */
46   char **arglist;
47
48   /* Non-zero if we saw a `-xfoo' language specification on the
49      command line.  Used to avoid adding our own -xc++ if the user
50      already gave a language for the file.  */
51   int saw_speclang = 0;
52
53   /* "-lm" or "-lmath" if it appears on the command line.  */
54   char *saw_math = 0;
55
56   /* "-lc" if it appears on the command line.  */
57   char *saw_libc = 0;
58
59   /* An array used to flag each argument that needs a bit set for
60      LANGSPEC, MATHLIB, or WITHLIBC.  */
61   int *args;
62
63   /* By default, we throw on the math library.  */
64   int need_math = 1;
65
66   /* The total number of arguments with the new stuff.  */
67   int argc;
68
69   /* The argument list.  */
70   char **argv;
71
72   /* The total number of arguments with the new stuff.  */
73   int num_args = 1;
74
75   argc = *in_argc;
76   argv = *in_argv;
77
78
79   args = (int *) xmalloc (argc * sizeof (int));
80   bzero ((char *) args, argc * sizeof (int));
81
82   for (i = 1; i < argc; i++)
83     {
84       /* If the previous option took an argument, we swallow it here.  */
85       if (quote)
86         {
87           quote = NULL;
88           continue;
89         }
90
91       /* We don't do this anymore, since we don't get them with minus
92          signs on them.  */
93       if (argv[i][0] == '\0' || argv[i][1] == '\0')
94         continue;
95
96       if (argv[i][0] == '-')
97         {
98           if (library != 0 && (strcmp (argv[i], "-nostdlib") == 0
99                                || strcmp (argv[i], "-nodefaultlibs") == 0))
100             {
101               library = 0;
102             }
103           else if (strcmp (argv[i], "-lm") == 0
104                    || strcmp (argv[i], "-lmath") == 0
105 #ifdef ALT_LIBM
106                    || strcmp (argv[i], ALT_LIBM) == 0
107 #endif
108                   )
109             {
110               args[i] |= MATHLIB;
111               need_math = 0;
112             }
113           else if (strcmp (argv[i], "-lc") == 0)
114             args[i] |= WITHLIBC;
115           else if (strcmp (argv[i], "-v") == 0)
116             {
117               saw_verbose_flag = 1;
118               if (argc == 2)
119                 {
120                   /* If they only gave us `-v', don't try to link
121                      in libg++.  */ 
122                   library = 0;
123                 }
124             }
125           else if (strncmp (argv[i], "-x", 2) == 0)
126             saw_speclang = 1;
127           else if (((argv[i][2] == '\0'
128                      && (char *)strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL)
129                     || strcmp (argv[i], "-Tdata") == 0))
130             quote = argv[i];
131           else if (library != 0 && ((argv[i][2] == '\0'
132                      && (char *) strchr ("cSEM", argv[i][1]) != NULL)
133                     || strcmp (argv[i], "-MM") == 0))
134             {
135               /* Don't specify libraries if we won't link, since that would
136                  cause a warning.  */
137               library = 0;
138               added -= 2;
139             }
140           else
141             /* Pass other options through.  */
142             continue;
143         }
144       else
145         {
146           int len; 
147
148           if (saw_speclang)
149             {
150               saw_speclang = 0;
151               continue;
152             }
153
154           /* If the filename ends in .c or .i, put options around it.
155              But not if a specified -x option is currently active.  */
156           len = strlen (argv[i]);
157           if (len > 2
158               && (argv[i][len - 1] == 'c' || argv[i][len - 1] == 'i')
159               && argv[i][len - 2] == '.')
160             {
161               args[i] |= LANGSPEC;
162               added += 2;
163             }
164         }
165     }
166
167   if (quote)
168     (*fn) ("argument to `%s' missing\n", quote);
169
170   /* If we know we don't have to do anything, bail now.  */
171   if (! added && ! library)
172     {
173       free (args);
174       return;
175     }
176
177   num_args = argc + added + need_math;
178   arglist = (char **) xmalloc (num_args * sizeof (char *));
179
180   /* NOTE: We start at 1 now, not 0.  */
181   for (i = 0, j = 0; i < argc; i++, j++)
182     {
183       arglist[j] = argv[i];
184
185       /* Make sure -lstdc++ is before the math library, since libstdc++
186          itself uses those math routines.  */
187       if (!saw_math && (args[i] & MATHLIB) && library)
188         {
189           --j;
190           saw_math = argv[i];
191         }
192
193       if (!saw_libc && (args[i] & WITHLIBC) && library)
194         {
195           --j;
196           saw_libc = argv[i];
197         }
198
199       /* Wrap foo.c and foo.i files in a language specification to
200          force the gcc compiler driver to run cc1plus on them.  */
201       if (args[i] & LANGSPEC)
202         {
203           int len = strlen (argv[i]);
204           if (argv[i][len - 1] == 'i')
205             arglist[j++] = "-xc++-cpp-output";
206           else
207             arglist[j++] = "-xc++";
208           arglist[j++] = argv[i];
209           arglist[j] = "-xnone";
210         }
211   }
212
213   /* Add `-lstdc++' if we haven't already done so.  */
214   if (library)
215     arglist[j++] = "-lstdc++";
216   if (saw_math)
217     arglist[j++] = saw_math;
218   else if (library)
219     arglist[j++] = MATH_LIBRARY;
220   if (saw_libc)
221     arglist[j++] = saw_libc;
222
223   arglist[j] = NULL;
224
225   *in_argc = j;
226   *in_argv = arglist;
227 }