OSDN Git Service

PR 33870
[pf3gnuchains/gcc-fork.git] / gcc / ada / gnatbl.c
1 /****************************************************************************
2  *                                                                          *
3  *                           GNAT COMPILER TOOLS                            *
4  *                                                                          *
5  *                               G N A T B L                                *
6  *                                                                          *
7  *                          C Implementation File                           *
8  *                                                                          *
9  *            Copyright (C) 1992-2007, 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 3,  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 COPYING3.  If not, go to *
19  * http://www.gnu.org/licenses for a complete copy of the license.          *
20  *                                                                          *
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  ****************************************************************************/
26
27 #ifdef VMS
28 #define _POSIX_EXIT 1
29 #endif
30
31 #include "config.h"
32 #include "system.h"
33
34 #if defined (__EMX__) || defined (MSDOS)
35 #include <process.h>
36 #endif
37 #include "adaint.h"
38
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;
55
56 int  link_arg_max = -1;
57 char **link_args = (char **) 0;
58 int  link_arg_index = -1;
59
60 char *gcc_B_arg = 0;
61
62 #ifndef DIR_SEPARATOR
63 #if defined (__EMX__)
64 #define DIR_SEPARATOR '\\'
65 #else
66 #define DIR_SEPARATOR '/'
67 #endif
68 #endif
69
70 static int linkonly = 0;
71
72 static void addarg (char *);
73 static void process_args (int *, char *[]);
74 \f
75 static void
76 addarg (char *str)
77 {
78   int i;
79
80   if (++link_arg_index >= link_arg_max)
81     {
82       char **new_link_args
83         = (char **) xcalloc (link_arg_max + 1000, sizeof (char *));
84
85       for (i = 0; i <= link_arg_max; i++)
86         new_link_args[i] = link_args[i];
87
88       if (link_args)
89         free (link_args);
90
91       link_arg_max += 1000;
92       link_args = new_link_args;
93     }
94
95   link_args[link_arg_index] = str;
96 }
97
98 static void
99 process_args (int *p_argc, char *argv[])
100 {
101   int i, j;
102
103   for (i = 1; i < *p_argc; i++)
104     {
105       /* -I is passed on to gnatbind */
106       if (! strncmp( argv[i], "-I", 2))
107         {
108           bind_arg_index += 1;
109           if (bind_arg_index >= BIND_ARG_MAX)
110             {
111               fprintf (stderr, "Too many arguments to gnatbind\n");
112               exit (-1);
113       }
114
115           bind_args[bind_arg_index] = argv[i];
116         }
117
118       /* -B is passed on to gcc */
119       if (! strncmp (argv[i], "-B", 2))
120         gcc_B_arg = argv[i];
121
122       /* -v turns on verbose option here and is passed on to gcc */
123
124       if (! strcmp (argv[i], "-v"))
125         verbose = 1;
126
127       if (! strcmp (argv[i], "-o"))
128         {
129           o_present = 1;
130           exec_file_name = argv[i + 1];
131         }
132
133       if (! strcmp (argv[i], "-g"))
134         g_present = 1;
135
136       if (! strcmp (argv[i], "-gnatbind"))
137         {
138           /* Explicit naming of binder. Grab the value then remove the
139              two arguments from the argument list. */
140           if ( i + 1 >= *p_argc )
141             {
142               fprintf (stderr, "Missing argument for -gnatbind\n");
143               exit (1);
144             }
145
146           binder_path = __gnat_locate_exec (argv[i + 1], (char *) ".");
147           if (!binder_path)
148             {
149               fprintf (stderr, "Could not locate binder: %s\n", argv[i + 1]);
150               exit (1);
151             }
152
153           for (j = i + 2; j < *p_argc; j++)
154             argv[j - 2] = argv[j];
155
156           (*p_argc) -= 2;
157           i--;
158         }
159
160     else if (! strcmp (argv[i], "-linkonly"))
161       {
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];
167
168         *p_argc -= 1;
169         i--;
170       }
171
172     else if (! strcmp (argv[i], "-gnatlink"))
173       {
174         /* Explicit naming of binder.  Grab the value then remove the
175            two arguments from the argument list. */
176         if (i + 1 >= *p_argc)
177           {
178             fprintf (stderr, "Missing argument for -gnatlink\n");
179             exit (1);
180           }
181
182         linker_path = __gnat_locate_exec (argv[i + 1], (char *) ".");
183         if (!linker_path)
184           {
185             fprintf (stderr, "Could not locate linker: %s\n", argv[i + 1]);
186             exit (1);
187           }
188
189         for (j = i + 2; j < *p_argc; j++)
190           argv[j - 2] = argv[j];
191         *p_argc -= 2;
192         i--;
193       }
194     }
195 }
196 extern int main (int, char **);
197
198 int
199 main (int argc, char **argv)
200 {
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;
213
214 #if defined (__EMX__) || defined(MSDOS)
215   char *tmppathval = malloc (strlen (pathval) + 3);
216   strcpy (tmppathval, ".;");
217   pathval = strcat (tmppathval, pathval);
218 #endif
219
220   process_args (&argc , argv);
221
222   if (argc == 1)
223     {
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);
249     }
250
251   if (!binder_path && !linkonly)
252     binder_path = __gnat_locate_exec ((char *) "gnatbind", pathval);
253
254   if (!binder_path && !linkonly)
255     {
256       fprintf (stderr, "Couldn't locate gnatbind\n");
257       exit (1);
258     }
259
260   if (!linker_path)
261     linker_path = __gnat_locate_exec ((char *) "gnatlink", pathval);
262     if (!linker_path)
263       {
264         fprintf (stderr, "Couldn't locate gnatlink\n");
265         exit (1);
266       }
267
268 #ifdef MSDOS
269   coff2exe_path = __gnat_locate_regular_file ("coff2exe.bat", pathval);
270   if (!coff2exe_path)
271     {
272       fprintf (stderr, "Couldn't locate %s\n", "coff2exe.bat");
273       exit (1);
274     }
275   else
276     coff2exe_args[0] = coff2exe_path;
277 #endif
278
279   addarg (linker_path);
280
281   for (i = 1; i < argc; i++)
282     {
283       int arg_len = strlen (argv[i]);
284
285       if (arg_len > 4 && ! strcmp (&argv[i][arg_len - 4], ".ali"))
286         {
287           if (done_an_ali)
288             {
289               fprintf (stderr,
290                        "Sorry - cannot handle more than one ALI file\n");
291               exit (1);
292             }
293
294           done_an_ali = 1;
295
296           if (__gnat_is_regular_file (argv[i]))
297             {
298               ali_file_name = argv[i];
299               if (!linkonly)
300                 {
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;
308
309                   if (verbose)
310                     {
311                       int i;
312                       for (i = 0; i < 2; i++)
313                         printf ("%s ", spawn_args[i]);
314
315                       putchar ('\n');
316                     }
317
318                   retcode = __gnat_portable_spawn (spawn_args);
319                   if (retcode != 0)
320                     exit (retcode);
321                 }
322             }
323           else
324             addarg (argv[i]);
325         }
326 #ifdef MSDOS
327       else if (!strcmp (argv[i], "-o"))
328         {
329           addarg (argv[i]);
330           if (i < argc)
331             i++;
332
333           {
334             char *ptr = strstr (argv[i], ".exe");
335
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;
341
342             addarg (coff2exe_args[1]);
343           }
344         }
345 #endif
346       else
347         addarg (argv[i]);
348     }
349
350   if (! done_an_ali)
351     {
352       fprintf (stderr, "No \".ali\" file specified\n");
353       exit (1);
354     }
355
356   addarg (ali_file_name);
357   addarg (NULL);
358
359   if (verbose)
360     {
361       int i;
362
363       for (i = 0; i < link_arg_index; i++)
364         printf ("%s ", link_args[i]);
365
366       putchar ('\n');
367     }
368
369   retcode = __gnat_portable_spawn (link_args);
370   if (retcode != 0)
371     exit (retcode);
372
373 #ifdef MSDOS
374   retcode = __gnat_portable_spawn (coff2exe_args);
375   if (retcode != 0)
376     exit (retcode);
377
378   if (!g_present)
379     {
380       del_command = malloc (strlen (coff2exe_args[1]) + 5);
381       sprintf (del_command, "del %s", coff2exe_args[1]);
382       retcode = system (del_command);
383     }
384 #endif
385
386   exit(0);
387 }