OSDN Git Service

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