OSDN Git Service

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