OSDN Git Service

* config/arc/arc-protos.h arc_select_cc_mode, gen_compare_reg):
[pf3gnuchains/gcc-fork.git] / gcc / config / alpha / vms-cc.c
1 /* VMS DEC C wrapper.
2    Copyright (C) 2001, 2003, 2007 Free Software Foundation, Inc.
3    Contributed by Douglas B. Rupp (rupp@gnat.com).
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20
21 /* This program is a wrapper around the VMS DEC C compiler.
22    It translates Unix style command line options into corresponding
23    VMS style qualifiers and then spawns the DEC C compiler.  */
24
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tm.h"
29
30 #undef PATH_SEPARATOR
31 #undef PATH_SEPARATOR_STR
32 #define PATH_SEPARATOR ','
33 #define PATH_SEPARATOR_STR ","
34
35 /* These can be set by command line arguments */
36 static int verbose = 0;
37 static int save_temps = 0;
38
39 static int comp_arg_max = -1;
40 static const char **comp_args = 0;
41 static int comp_arg_index = -1;
42 static char *objfilename = 0;
43
44 static char *system_search_dirs = (char *) "";
45 static char *search_dirs;
46
47 static char *default_defines = (char *) "";
48 static char *defines;
49
50 /* Translate a Unix syntax directory specification into VMS syntax.
51    If indicators of VMS syntax found, return input string.  */
52 static char *to_host_dir_spec (char *);
53
54 /* Translate a Unix syntax file specification into VMS syntax.
55    If indicators of VMS syntax found, return input string.  */
56 static char *to_host_file_spec (char *);
57
58 /* Add a translated arg to the list to be passed to DEC CC.  */
59 static void addarg (const char *);
60
61 /* Preprocess the number of args in P_ARGC and contained in ARGV.
62    Look for special flags, etc. that must be handled first.  */
63 static void preprocess_args (int *, char **);
64
65 /* Process the number of args in P_ARGC and contained in ARGV. Look
66    for special flags, etc. that must be handled for the VMS compiler.  */
67 static void process_args (int *, char **);
68
69 /* Action routine called by decc$to_vms */
70 static int translate_unix (char *, int);
71 \f
72 /* Add the argument contained in STR to the list of arguments to pass to the
73    compiler.  */
74
75 static void
76 addarg (const char *str)
77 {
78   int i;
79
80   if (++comp_arg_index >= comp_arg_max)
81     {
82       const char **new_comp_args
83         = (const char **) xcalloc (comp_arg_max + 1000, sizeof (char *));
84
85       for (i = 0; i <= comp_arg_max; i++)
86         new_comp_args [i] = comp_args [i];
87
88       if (comp_args)
89         free (comp_args);
90
91       comp_arg_max += 1000;
92       comp_args = new_comp_args;
93     }
94
95   comp_args [comp_arg_index] = str;
96 }
97
98 static void
99 preprocess_args (int *p_argc, char *argv[])
100 {
101   int i;
102
103   for (i = 1; i < *p_argc; i++)
104     {
105       if (strcmp (argv[i], "-o") == 0)
106         {
107           char *buff, *ptr;
108
109           i++;
110           ptr = to_host_file_spec (argv[i]);
111           objfilename = xstrdup (ptr);
112           buff = concat ("/obj=", ptr, NULL);
113           addarg (buff);
114         }
115     }
116 }
117
118 static void
119 process_args (int *p_argc, char *argv[])
120 {
121   int i;
122
123   for (i = 1; i < *p_argc; i++)
124     {
125       if (strlen (argv[i]) < 2)
126         continue;
127
128       if (strncmp (argv[i], "-I", 2) == 0)
129         {
130           char *ptr;
131           int new_len, search_dirs_len;
132
133           ptr = to_host_dir_spec (&argv[i][2]);
134           new_len = strlen (ptr);
135           search_dirs_len = strlen (search_dirs);
136
137           search_dirs = xrealloc (search_dirs, search_dirs_len + new_len + 2);
138           if (search_dirs_len > 0)
139             strcat (search_dirs, PATH_SEPARATOR_STR);
140           strcat (search_dirs, ptr);
141         }
142       else if (strncmp (argv[i], "-D", 2) == 0)
143         {
144           char *ptr;
145           int new_len, defines_len;
146
147           ptr = &argv[i][2];
148           new_len = strlen (ptr);
149           defines_len = strlen (defines);
150
151           defines = xrealloc (defines, defines_len + new_len + 4);
152           if (defines_len > 0)
153             strcat (defines, ",");
154
155           strcat (defines, "\"");
156           strcat (defines, ptr);
157           strcat (defines, "\"");
158         }
159       else if (strcmp (argv[i], "-v") == 0)
160         verbose = 1;
161       else if (strcmp (argv[i], "-g0") == 0)
162         addarg ("/nodebug");
163       else if (strcmp (argv[i], "-O0") == 0)
164         addarg ("/noopt");
165       else if (strncmp (argv[i], "-g", 2) == 0)
166         addarg ("/debug");
167       else if (strcmp (argv[i], "-E") == 0)
168         addarg ("/preprocess");
169       else if (strcmp (argv[i], "-save-temps") == 0)
170         save_temps = 1;
171     }
172 }
173
174 /* The main program.  Spawn the VMS DEC C compiler after fixing up the
175    Unix-like flags and args to be what VMS DEC C wants.  */
176
177 typedef struct dsc {unsigned short len, mbz; char *adr; } Descr;
178
179 int
180 main (int argc, char **argv)
181 {
182   int i;
183   char cwdev [128], *devptr;
184   int devlen;
185   char *cwd = getcwd (0, 1024);
186
187   devptr = strchr (cwd, ':');
188   devlen = (devptr - cwd) + 1;
189   strncpy (cwdev, cwd, devlen);
190   cwdev [devlen] = '\0';
191
192   search_dirs = xstrdup (system_search_dirs);
193   defines = xstrdup (default_defines);
194
195   addarg ("cc");
196   preprocess_args (&argc , argv);
197   process_args (&argc , argv);
198
199   if (strlen (search_dirs) > 0)
200     {
201       addarg ("/include=(");
202       addarg (search_dirs);
203       addarg (")");
204     }
205
206   if (strlen (defines) > 0)
207     {
208       addarg ("/define=(");
209       addarg (defines);
210       addarg (")");
211     }
212
213   for (i = 1; i < argc; i++)
214     {
215       int arg_len = strlen (argv[i]);
216
217       if (strcmp (argv[i], "-o") == 0)
218         i++;
219       else if (strcmp (argv[i], "-v" ) == 0
220                || strcmp (argv[i], "-E") == 0
221                || strcmp (argv[i], "-c") == 0
222                || strncmp (argv[i], "-g", 2 ) == 0
223                || strncmp (argv[i], "-O", 2 ) == 0
224                || strcmp (argv[i], "-save-temps") == 0
225                || (arg_len > 2 && strncmp (argv[i], "-I", 2) == 0)
226                || (arg_len > 2 && strncmp (argv[i], "-D", 2) == 0))
227         ;
228
229       /* Unix style file specs and VMS style switches look alike, so assume
230          an arg consisting of one and only one slash, and that being first, is
231          really a switch.  */
232       else if ((argv[i][0] == '/') && (strchr (&argv[i][1], '/') == 0))
233         addarg (argv[i]);
234       else
235         {
236           /* Assume filename arg */
237           char buff [256], *ptr;
238
239           ptr = to_host_file_spec (argv[i]);
240           arg_len = strlen (ptr);
241
242           if (ptr[0] == '[')
243             sprintf (buff, "%s%s", cwdev, ptr);
244           else if (strchr (ptr, ':'))
245             sprintf (buff, "%s", ptr);
246           else
247             sprintf (buff, "%s%s", cwd, ptr);
248
249           ptr = xstrdup (buff);
250           addarg (ptr);
251         }
252     }
253
254   addarg (NULL);
255
256   if (verbose)
257     {
258       int i;
259
260       for (i = 0; i < comp_arg_index; i++)
261         printf ("%s ", comp_args [i]);
262
263       putchar ('\n');
264     }
265
266   {
267     int i;
268     int len = 0;
269
270     for (i = 0; comp_args[i]; i++)
271       len = len + strlen (comp_args[i]) + 1;
272
273     {
274       char *allargs = (char *) alloca (len + 1);
275       Descr cmd;
276       int status;
277       int status1 = 1;
278
279       for (i = 0; i < len + 1; i++)
280         allargs [i] = 0;
281
282       for (i = 0; comp_args [i]; i++)
283         {
284           strcat (allargs, comp_args [i]);
285           strcat (allargs, " ");
286         }
287
288       cmd.adr = allargs;
289       cmd.len = len;
290       cmd.mbz = 0;
291
292       i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status);
293
294       if ((i & 1) != 1)
295         {
296           LIB$SIGNAL (i);
297           exit (1);
298         }
299
300       if ((status & 1) == 1 && (status1 & 1) == 1)
301         exit (0);
302
303       exit (1);
304     }
305   }
306 }
307
308 static char new_host_filespec [255];
309 static char new_host_dirspec [255];
310 static char filename_buff [256];
311
312 static int
313 translate_unix (char *name, int type ATTRIBUTE_UNUSED)
314 {
315   strcpy (filename_buff, name);
316   return 0;
317 }
318
319 static char *
320 to_host_dir_spec (char *dirspec)
321 {
322   int len = strlen (dirspec);
323
324   strcpy (new_host_dirspec, dirspec);
325
326   if (strchr (new_host_dirspec, ']') || strchr (new_host_dirspec, ':'))
327     return new_host_dirspec;
328
329   while (len > 1 && new_host_dirspec [len-1] == '/')
330     {
331       new_host_dirspec [len-1] = 0;
332       len--;
333     }
334
335   decc$to_vms (new_host_dirspec, translate_unix, 1, 2);
336   strcpy (new_host_dirspec, filename_buff);
337
338   return new_host_dirspec;
339
340 }
341
342 static char *
343 to_host_file_spec (char *filespec)
344 {
345   strcpy (new_host_filespec, "");
346   if (strchr (filespec, ']') || strchr (filespec, ':'))
347     strcpy (new_host_filespec, filespec);
348   else
349     {
350       decc$to_vms (filespec, translate_unix, 1, 1);
351       strcpy (new_host_filespec, filename_buff);
352     }
353
354   return new_host_filespec;
355 }