2008-07-01 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[official-gcc.git] / gcc / config / alpha / vms-cc.c
blob9ba2707240f36b24dad92817798040341529d5e1
1 /* VMS DEC C wrapper.
2 Copyright (C) 2001, 2003, 2007 Free Software Foundation, Inc.
3 Contributed by Douglas B. Rupp (rupp@gnat.com).
5 This file is part of GCC.
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.
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.
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/>. */
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. */
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tm.h"
30 #undef PATH_SEPARATOR
31 #undef PATH_SEPARATOR_STR
32 #define PATH_SEPARATOR ','
33 #define PATH_SEPARATOR_STR ","
35 /* These can be set by command line arguments */
36 static int verbose = 0;
37 static int save_temps = 0;
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;
44 static char *system_search_dirs = (char *) "";
45 static char *search_dirs;
47 static char *default_defines = (char *) "";
48 static char *defines;
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 *);
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 *);
58 /* Add a translated arg to the list to be passed to DEC CC. */
59 static void addarg (const char *);
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 **);
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 **);
69 /* Action routine called by decc$to_vms */
70 static int translate_unix (char *, int);
72 /* Add the argument contained in STR to the list of arguments to pass to the
73 compiler. */
75 static void
76 addarg (const char *str)
78 int i;
80 if (++comp_arg_index >= comp_arg_max)
82 const char **new_comp_args
83 = (const char **) xcalloc (comp_arg_max + 1000, sizeof (char *));
85 for (i = 0; i <= comp_arg_max; i++)
86 new_comp_args [i] = comp_args [i];
88 if (comp_args)
89 free (comp_args);
91 comp_arg_max += 1000;
92 comp_args = new_comp_args;
95 comp_args [comp_arg_index] = str;
98 static void
99 preprocess_args (int *p_argc, char *argv[])
101 int i;
103 for (i = 1; i < *p_argc; i++)
105 if (strcmp (argv[i], "-o") == 0)
107 char *buff, *ptr;
109 i++;
110 ptr = to_host_file_spec (argv[i]);
111 objfilename = xstrdup (ptr);
112 buff = concat ("/obj=", ptr, NULL);
113 addarg (buff);
118 static void
119 process_args (int *p_argc, char *argv[])
121 int i;
123 for (i = 1; i < *p_argc; i++)
125 if (strlen (argv[i]) < 2)
126 continue;
128 if (strncmp (argv[i], "-I", 2) == 0)
130 char *ptr;
131 int new_len, search_dirs_len;
133 ptr = to_host_dir_spec (&argv[i][2]);
134 new_len = strlen (ptr);
135 search_dirs_len = strlen (search_dirs);
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);
142 else if (strncmp (argv[i], "-D", 2) == 0)
144 char *ptr;
145 int new_len, defines_len;
147 ptr = &argv[i][2];
148 new_len = strlen (ptr);
149 defines_len = strlen (defines);
151 defines = xrealloc (defines, defines_len + new_len + 4);
152 if (defines_len > 0)
153 strcat (defines, ",");
155 strcat (defines, "\"");
156 strcat (defines, ptr);
157 strcat (defines, "\"");
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;
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. */
177 typedef struct dsc {unsigned short len, mbz; char *adr; } Descr;
180 main (int argc, char **argv)
182 int i;
183 char cwdev [128], *devptr;
184 int devlen;
185 char *cwd = getcwd (0, 1024);
187 devptr = strchr (cwd, ':');
188 devlen = (devptr - cwd) + 1;
189 strncpy (cwdev, cwd, devlen);
190 cwdev [devlen] = '\0';
192 search_dirs = xstrdup (system_search_dirs);
193 defines = xstrdup (default_defines);
195 addarg ("cc");
196 preprocess_args (&argc , argv);
197 process_args (&argc , argv);
199 if (strlen (search_dirs) > 0)
201 addarg ("/include=(");
202 addarg (search_dirs);
203 addarg (")");
206 if (strlen (defines) > 0)
208 addarg ("/define=(");
209 addarg (defines);
210 addarg (")");
213 for (i = 1; i < argc; i++)
215 int arg_len = strlen (argv[i]);
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))
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
236 /* Assume filename arg */
237 char buff [256], *ptr;
239 ptr = to_host_file_spec (argv[i]);
240 arg_len = strlen (ptr);
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);
249 ptr = xstrdup (buff);
250 addarg (ptr);
254 addarg (NULL);
256 if (verbose)
258 int i;
260 for (i = 0; i < comp_arg_index; i++)
261 printf ("%s ", comp_args [i]);
263 putchar ('\n');
267 int i;
268 int len = 0;
270 for (i = 0; comp_args[i]; i++)
271 len = len + strlen (comp_args[i]) + 1;
274 char *allargs = (char *) alloca (len + 1);
275 Descr cmd;
276 int status;
277 int status1 = 1;
279 for (i = 0; i < len + 1; i++)
280 allargs [i] = 0;
282 for (i = 0; comp_args [i]; i++)
284 strcat (allargs, comp_args [i]);
285 strcat (allargs, " ");
288 cmd.adr = allargs;
289 cmd.len = len;
290 cmd.mbz = 0;
292 i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status);
294 if ((i & 1) != 1)
296 LIB$SIGNAL (i);
297 exit (1);
300 if ((status & 1) == 1 && (status1 & 1) == 1)
301 exit (0);
303 exit (1);
308 static char new_host_filespec [255];
309 static char new_host_dirspec [255];
310 static char filename_buff [256];
312 static int
313 translate_unix (char *name, int type ATTRIBUTE_UNUSED)
315 strcpy (filename_buff, name);
316 return 0;
319 static char *
320 to_host_dir_spec (char *dirspec)
322 int len = strlen (dirspec);
324 strcpy (new_host_dirspec, dirspec);
326 if (strchr (new_host_dirspec, ']') || strchr (new_host_dirspec, ':'))
327 return new_host_dirspec;
329 while (len > 1 && new_host_dirspec [len-1] == '/')
331 new_host_dirspec [len-1] = 0;
332 len--;
335 decc$to_vms (new_host_dirspec, translate_unix, 1, 2);
336 strcpy (new_host_dirspec, filename_buff);
338 return new_host_dirspec;
342 static char *
343 to_host_file_spec (char *filespec)
345 strcpy (new_host_filespec, "");
346 if (strchr (filespec, ']') || strchr (filespec, ':'))
347 strcpy (new_host_filespec, filespec);
348 else
350 decc$to_vms (filespec, translate_unix, 1, 1);
351 strcpy (new_host_filespec, filename_buff);
354 return new_host_filespec;