Merge from the pain train
[official-gcc.git] / gcc / ada / gnatbl.c
blobead189ff261387abae7d8bc5128e3b20dd675226
1 /****************************************************************************
2 * *
3 * GNAT COMPILER TOOLS *
4 * *
5 * G N A T B L *
6 * *
7 * C Implementation File *
8 * *
9 * Copyright (C) 1992-2005 Free Software Foundation, Inc. *
10 * *
11 * GNAT is free software; you can redistribute it and/or modify it under *
12 * terms of the GNU General Public License as published by the Free Soft- *
13 * ware Foundation; either version 2, or (at your option) any later ver- *
14 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
15 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
17 * for more details. You should have received a copy of the GNU General *
18 * Public License distributed with GNAT; see file COPYING. If not, write *
19 * to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, *
20 * MA 02111-1307, USA. *
21 * *
22 * GNAT was originally developed by the GNAT team at New York University. *
23 * Extensive contributions were provided by Ada Core Technologies Inc. *
24 * *
25 ****************************************************************************/
27 #ifdef VMS
28 #define _POSIX_EXIT 1
29 #endif
31 #include "config.h"
32 #include "system.h"
34 #if defined (__EMX__) || defined (MSDOS)
35 #include <process.h>
36 #endif
37 #include "adaint.h"
39 /* These can be set by command line arguments */
40 char *binder_path = 0;
41 char *linker_path = 0;
42 char *exec_file_name = 0;
43 char *ali_file_name = 0;
44 #define BIND_ARG_MAX 512
45 char *bind_args[BIND_ARG_MAX];
46 int bind_arg_index = -1;
47 #ifdef MSDOS
48 char *coff2exe_path = 0;
49 char *coff2exe_args[] = {(char *) 0, (char *) 0};
50 char *del_command = 0;
51 #endif
52 int verbose = 0;
53 int o_present = 0;
54 int g_present = 0;
56 int link_arg_max = -1;
57 char **link_args = (char **) 0;
58 int link_arg_index = -1;
60 char *gcc_B_arg = 0;
62 #ifndef DIR_SEPARATOR
63 #if defined (__EMX__)
64 #define DIR_SEPARATOR '\\'
65 #else
66 #define DIR_SEPARATOR '/'
67 #endif
68 #endif
70 static int linkonly = 0;
72 static void addarg (char *);
73 static void process_args (int *, char *[]);
75 static void
76 addarg (char *str)
78 int i;
80 if (++link_arg_index >= link_arg_max)
82 char **new_link_args
83 = (char **) xcalloc (link_arg_max + 1000, sizeof (char *));
85 for (i = 0; i <= link_arg_max; i++)
86 new_link_args[i] = link_args[i];
88 if (link_args)
89 free (link_args);
91 link_arg_max += 1000;
92 link_args = new_link_args;
95 link_args[link_arg_index] = str;
98 static void
99 process_args (int *p_argc, char *argv[])
101 int i, j;
103 for (i = 1; i < *p_argc; i++)
105 /* -I is passed on to gnatbind */
106 if (! strncmp( argv[i], "-I", 2))
108 bind_arg_index += 1;
109 if (bind_arg_index >= BIND_ARG_MAX)
111 fprintf (stderr, "Too many arguments to gnatbind\n");
112 exit (-1);
115 bind_args[bind_arg_index] = argv[i];
118 /* -B is passed on to gcc */
119 if (! strncmp (argv[i], "-B", 2))
120 gcc_B_arg = argv[i];
122 /* -v turns on verbose option here and is passed on to gcc */
124 if (! strcmp (argv[i], "-v"))
125 verbose = 1;
127 if (! strcmp (argv[i], "-o"))
129 o_present = 1;
130 exec_file_name = argv[i + 1];
133 if (! strcmp (argv[i], "-g"))
134 g_present = 1;
136 if (! strcmp (argv[i], "-gnatbind"))
138 /* Explicit naming of binder. Grab the value then remove the
139 two arguments from the argument list. */
140 if ( i + 1 >= *p_argc )
142 fprintf (stderr, "Missing argument for -gnatbind\n");
143 exit (1);
146 binder_path = __gnat_locate_exec (argv[i + 1], (char *) ".");
147 if (!binder_path)
149 fprintf (stderr, "Could not locate binder: %s\n", argv[i + 1]);
150 exit (1);
153 for (j = i + 2; j < *p_argc; j++)
154 argv[j - 2] = argv[j];
156 (*p_argc) -= 2;
157 i--;
160 else if (! strcmp (argv[i], "-linkonly"))
162 /* Don't call the binder. Set the flag and then remove the
163 argument from the argument list. */
164 linkonly = 1;
165 for (j = i + 1; j < *p_argc; j++)
166 argv[j - 1] = argv[j];
168 *p_argc -= 1;
169 i--;
172 else if (! strcmp (argv[i], "-gnatlink"))
174 /* Explicit naming of binder. Grab the value then remove the
175 two arguments from the argument list. */
176 if (i + 1 >= *p_argc)
178 fprintf (stderr, "Missing argument for -gnatlink\n");
179 exit (1);
182 linker_path = __gnat_locate_exec (argv[i + 1], (char *) ".");
183 if (!linker_path)
185 fprintf (stderr, "Could not locate linker: %s\n", argv[i + 1]);
186 exit (1);
189 for (j = i + 2; j < *p_argc; j++)
190 argv[j - 2] = argv[j];
191 *p_argc -= 2;
192 i--;
196 extern int main (int, char **);
199 main (int argc, char **argv)
201 int i, j;
202 int done_an_ali = 0;
203 int retcode;
204 #ifdef VMS
205 /* Warning: getenv only retrieves the first directory in VAXC$PATH */
206 char *pathval =
207 xstrdup (__gnat_to_canonical_dir_spec (getenv ("VAXC$PATH"), 0));
208 #else
209 char *pathval = getenv ("PATH");
210 #endif
211 char *spawn_args[5];
212 int spawn_index = 0;
214 #if defined (__EMX__) || defined(MSDOS)
215 char *tmppathval = malloc (strlen (pathval) + 3);
216 strcpy (tmppathval, ".;");
217 pathval = strcat (tmppathval, pathval);
218 #endif
220 process_args (&argc , argv);
222 if (argc == 1)
224 fprintf
225 (stdout,
226 "Usage: %s 'name'.ali\n", argv[0]);
227 fprintf
228 (stdout,
229 " [-o exec_name] -- by default it is 'name'\n");
230 fprintf
231 (stdout,
232 " [-v] -- verbose mode\n");
233 fprintf
234 (stdout,
235 " [-linkonly] -- doesn't call binder\n");
236 fprintf
237 (stdout,
238 " [-gnatbind name] -- full name for gnatbind\n");
239 fprintf
240 (stdout,
241 " [-gnatlink name] -- full name for linker (gcc)\n");
242 fprintf
243 (stdout,
244 " [list of objects] -- non Ada binaries\n");
245 fprintf
246 (stdout,
247 " [linker options] -- other options for linker\n");
248 exit (1);
251 if (!binder_path && !linkonly)
252 binder_path = __gnat_locate_exec ((char *) "gnatbind", pathval);
254 if (!binder_path && !linkonly)
256 fprintf (stderr, "Couldn't locate gnatbind\n");
257 exit (1);
260 if (!linker_path)
261 linker_path = __gnat_locate_exec ((char *) "gnatlink", pathval);
262 if (!linker_path)
264 fprintf (stderr, "Couldn't locate gnatlink\n");
265 exit (1);
268 #ifdef MSDOS
269 coff2exe_path = __gnat_locate_regular_file ("coff2exe.bat", pathval);
270 if (!coff2exe_path)
272 fprintf (stderr, "Couldn't locate %s\n", "coff2exe.bat");
273 exit (1);
275 else
276 coff2exe_args[0] = coff2exe_path;
277 #endif
279 addarg (linker_path);
281 for (i = 1; i < argc; i++)
283 int arg_len = strlen (argv[i]);
285 if (arg_len > 4 && ! strcmp (&argv[i][arg_len - 4], ".ali"))
287 if (done_an_ali)
289 fprintf (stderr,
290 "Sorry - cannot handle more than one ALI file\n");
291 exit (1);
294 done_an_ali = 1;
296 if (__gnat_is_regular_file (argv[i]))
298 ali_file_name = argv[i];
299 if (!linkonly)
301 /* Run gnatbind */
302 spawn_index = 0;
303 spawn_args[spawn_index++] = binder_path;
304 spawn_args[spawn_index++] = ali_file_name;
305 for (j = 0 ; j <= bind_arg_index ; j++ )
306 spawn_args[spawn_index++] = bind_args[j];
307 spawn_args[spawn_index] = 0;
309 if (verbose)
311 int i;
312 for (i = 0; i < 2; i++)
313 printf ("%s ", spawn_args[i]);
315 putchar ('\n');
318 retcode = __gnat_portable_spawn (spawn_args);
319 if (retcode != 0)
320 exit (retcode);
323 else
324 addarg (argv[i]);
326 #ifdef MSDOS
327 else if (!strcmp (argv[i], "-o"))
329 addarg (argv[i]);
330 if (i < argc)
331 i++;
334 char *ptr = strstr (argv[i], ".exe");
336 arg_len = strlen (argv[i]);
337 coff2exe_args[1] = malloc (arg_len + 1);
338 strcpy (coff2exe_args[1], argv[i]);
339 if (ptr != NULL && strlen (ptr) == 4)
340 coff2exe_args[1][arg_len-4] = 0;
342 addarg (coff2exe_args[1]);
345 #endif
346 else
347 addarg (argv[i]);
350 if (! done_an_ali)
352 fprintf (stderr, "No \".ali\" file specified\n");
353 exit (1);
356 addarg (ali_file_name);
357 addarg (NULL);
359 if (verbose)
361 int i;
363 for (i = 0; i < link_arg_index; i++)
364 printf ("%s ", link_args[i]);
366 putchar ('\n');
369 retcode = __gnat_portable_spawn (link_args);
370 if (retcode != 0)
371 exit (retcode);
373 #ifdef MSDOS
374 retcode = __gnat_portable_spawn (coff2exe_args);
375 if (retcode != 0)
376 exit (retcode);
378 if (!g_present)
380 del_command = malloc (strlen (coff2exe_args[1]) + 5);
381 sprintf (del_command, "del %s", coff2exe_args[1]);
382 retcode = system (del_command);
384 #endif
386 exit(0);