OSDN Git Service

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