OSDN Git Service

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