Fix thinko
[official-gcc.git] / gcc / ada / gnatbl.c
blob72f85169fd8ae1efaa7568702505aeea64dfd6f6
1 /****************************************************************************
2 * *
3 * GNAT COMPILER TOOLS *
4 * *
5 * G N A T B L *
6 * *
7 * C Implementation File *
8 * *
9 * Copyright (C) 1992-2001 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 #include "config.h"
28 #include "system.h"
30 #if defined (__EMX__) || defined (MSDOS)
31 #include <process.h>
32 #endif
33 #include "adaint.h"
35 #ifdef VMS
36 #ifdef exit
37 #undef exit
38 #endif
39 #define exit __posix_exit
40 #endif
42 /* These can be set by command line arguments */
43 char *binder_path = 0;
44 char *linker_path = 0;
45 char *exec_file_name = 0;
46 char *ali_file_name = 0;
47 #define BIND_ARG_MAX 512
48 char *bind_args[BIND_ARG_MAX];
49 int bind_arg_index = -1;
50 #ifdef MSDOS
51 char *coff2exe_path = 0;
52 char *coff2exe_args[] = {(char *) 0, (char *) 0};
53 char *del_command = 0;
54 #endif
55 int verbose = 0;
56 int o_present = 0;
57 int g_present = 0;
59 int link_arg_max = -1;
60 char **link_args = (char **) 0;
61 int link_arg_index = -1;
63 char *gcc_B_arg = 0;
65 #ifndef DIR_SEPARATOR
66 #if defined (__EMX__)
67 #define DIR_SEPARATOR '\\'
68 #else
69 #define DIR_SEPARATOR '/'
70 #endif
71 #endif
73 static int linkonly = 0;
75 static void addarg PARAMS ((char *));
76 static void process_args PARAMS ((int *, char *[]));
78 static void
79 addarg (str)
80 char *str;
82 int i;
84 if (++link_arg_index >= link_arg_max)
86 char **new_link_args
87 = (char **) xcalloc (link_arg_max + 1000, sizeof (char *));
89 for (i = 0; i <= link_arg_max; i++)
90 new_link_args[i] = link_args[i];
92 if (link_args)
93 free (link_args);
95 link_arg_max += 1000;
96 link_args = new_link_args;
99 link_args[link_arg_index] = str;
102 static void
103 process_args (p_argc, argv)
104 int *p_argc;
105 char *argv[];
107 int i, j;
109 for (i = 1; i < *p_argc; i++)
111 /* -I is passed on to gnatbind */
112 if (! strncmp( argv[i], "-I", 2))
114 bind_arg_index += 1;
115 if (bind_arg_index >= BIND_ARG_MAX)
117 fprintf (stderr, "Too many arguments to gnatbind\n");
118 exit (-1);
121 bind_args[bind_arg_index] = argv[i];
124 /* -B is passed on to gcc */
125 if (! strncmp (argv[i], "-B", 2))
126 gcc_B_arg = argv[i];
128 /* -v turns on verbose option here and is passed on to gcc */
130 if (! strcmp (argv[i], "-v"))
131 verbose = 1;
133 if (! strcmp (argv[i], "-o"))
135 o_present = 1;
136 exec_file_name = argv[i + 1];
139 if (! strcmp (argv[i], "-g"))
140 g_present = 1;
142 if (! strcmp (argv[i], "-gnatbind"))
144 /* Explicit naming of binder. Grab the value then remove the
145 two arguments from the argument list. */
146 if ( i + 1 >= *p_argc )
148 fprintf (stderr, "Missing argument for -gnatbind\n");
149 exit (1);
152 binder_path = __gnat_locate_exec (argv[i + 1], (char *) ".");
153 if (!binder_path)
155 fprintf (stderr, "Could not locate binder: %s\n", argv[i + 1]);
156 exit (1);
159 for (j = i + 2; j < *p_argc; j++)
160 argv[j - 2] = argv[j];
162 (*p_argc) -= 2;
163 i--;
166 else if (! strcmp (argv[i], "-linkonly"))
168 /* Don't call the binder. Set the flag and then remove the
169 argument from the argument list. */
170 linkonly = 1;
171 for (j = i + 1; j < *p_argc; j++)
172 argv[j - 1] = argv[j];
174 *p_argc -= 1;
175 i--;
178 else if (! strcmp (argv[i], "-gnatlink"))
180 /* Explicit naming of binder. Grab the value then remove the
181 two arguments from the argument list. */
182 if (i + 1 >= *p_argc)
184 fprintf (stderr, "Missing argument for -gnatlink\n");
185 exit (1);
188 linker_path = __gnat_locate_exec (argv[i + 1], (char *) ".");
189 if (!linker_path)
191 fprintf (stderr, "Could not locate linker: %s\n", argv[i + 1]);
192 exit (1);
195 for (j = i + 2; j < *p_argc; j++)
196 argv[j - 2] = argv[j];
197 *p_argc -= 2;
198 i--;
202 extern int main PARAMS ((int, char **));
205 main (argc, argv)
206 int argc;
207 char **argv;
209 int i, j;
210 int done_an_ali = 0;
211 int retcode;
212 #ifdef VMS
213 /* Warning: getenv only retrieves the first directory in VAXC$PATH */
214 char *pathval =
215 xstrdup (__gnat_to_canonical_dir_spec (getenv ("VAXC$PATH"), 0));
216 #else
217 char *pathval = getenv ("PATH");
218 #endif
219 char *spawn_args[5];
220 int spawn_index = 0;
222 #if defined (__EMX__) || defined(MSDOS)
223 char *tmppathval = malloc (strlen (pathval) + 3);
224 strcpy (tmppathval, ".;");
225 pathval = strcat (tmppathval, pathval);
226 #endif
228 process_args (&argc , argv);
230 if (argc == 1)
232 fprintf
233 (stdout,
234 "Usage: %s 'name'.ali\n", argv[0]);
235 fprintf
236 (stdout,
237 " [-o exec_name] -- by default it is 'name'\n");
238 fprintf
239 (stdout,
240 " [-v] -- verbose mode\n");
241 fprintf
242 (stdout,
243 " [-linkonly] -- doesn't call binder\n");
244 fprintf
245 (stdout,
246 " [-gnatbind name] -- full name for gnatbind\n");
247 fprintf
248 (stdout,
249 " [-gnatlink name] -- full name for linker (gcc)\n");
250 fprintf
251 (stdout,
252 " [list of objects] -- non Ada binaries\n");
253 fprintf
254 (stdout,
255 " [linker options] -- other options for linker\n");
256 exit (1);
259 if (!binder_path && !linkonly)
260 binder_path = __gnat_locate_exec ((char *) "gnatbind", pathval);
262 if (!binder_path && !linkonly)
264 fprintf (stderr, "Couldn't locate gnatbind\n");
265 exit (1);
268 if (!linker_path)
269 linker_path = __gnat_locate_exec ((char *) "gnatlink", pathval);
270 if (!linker_path)
272 fprintf (stderr, "Couldn't locate gnatlink\n");
273 exit (1);
276 #ifdef MSDOS
277 coff2exe_path = __gnat_locate_regular_file ("coff2exe.bat", pathval);
278 if (!coff2exe_path)
280 fprintf (stderr, "Couldn't locate %s\n", "coff2exe.bat");
281 exit (1);
283 else
284 coff2exe_args[0] = coff2exe_path;
285 #endif
287 addarg (linker_path);
289 for (i = 1; i < argc; i++)
291 int arg_len = strlen (argv[i]);
293 if (arg_len > 4 && ! strcmp (&argv[i][arg_len - 4], ".ali"))
295 if (done_an_ali)
297 fprintf (stderr,
298 "Sorry - cannot handle more than one ALI file\n");
299 exit (1);
302 done_an_ali = 1;
304 if (__gnat_is_regular_file (argv[i]))
306 ali_file_name = argv[i];
307 if (!linkonly)
309 /* Run gnatbind */
310 spawn_index = 0;
311 spawn_args[spawn_index++] = binder_path;
312 spawn_args[spawn_index++] = ali_file_name;
313 for (j = 0 ; j <= bind_arg_index ; j++ )
314 spawn_args[spawn_index++] = bind_args[j];
315 spawn_args[spawn_index] = 0;
317 if (verbose)
319 int i;
320 for (i = 0; i < 2; i++)
321 printf ("%s ", spawn_args[i]);
323 putchar ('\n');
326 retcode = __gnat_portable_spawn (spawn_args);
327 if (retcode != 0)
328 exit (retcode);
331 else
332 addarg (argv[i]);
334 #ifdef MSDOS
335 else if (!strcmp (argv[i], "-o"))
337 addarg (argv[i]);
338 if (i < argc)
339 i++;
342 char *ptr = strstr (argv[i], ".exe");
344 arg_len = strlen (argv[i]);
345 coff2exe_args[1] = malloc (arg_len + 1);
346 strcpy (coff2exe_args[1], argv[i]);
347 if (ptr != NULL && strlen (ptr) == 4)
348 coff2exe_args[1][arg_len-4] = 0;
350 addarg (coff2exe_args[1]);
353 #endif
354 else
355 addarg (argv[i]);
358 if (! done_an_ali)
360 fprintf (stderr, "No \".ali\" file specified\n");
361 exit (1);
364 addarg (ali_file_name);
365 addarg (NULL);
367 if (verbose)
369 int i;
371 for (i = 0; i < link_arg_index; i++)
372 printf ("%s ", link_args[i]);
374 putchar ('\n');
377 retcode = __gnat_portable_spawn (link_args);
378 if (retcode != 0)
379 exit (retcode);
381 #ifdef MSDOS
382 retcode = __gnat_portable_spawn (coff2exe_args);
383 if (retcode != 0)
384 exit (retcode);
386 if (!g_present)
388 del_command = malloc (strlen (coff2exe_args[1]) + 5);
389 sprintf (del_command, "del %s", coff2exe_args[1]);
390 retcode = system (del_command);
392 #endif
394 exit(0);