OSDN Git Service

* 41intnam.ads, 42intnam.ads, 4aintnam.ads, 4cintnam.ads,
[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  *                             $Revision$
10  *                                                                          *
11  *          Copyright (C) 1992-2001 Free Software Foundation, Inc.          *
12  *                                                                          *
13  * GNAT is free software;  you can  redistribute it  and/or modify it under *
14  * terms of the  GNU General Public License as published  by the Free Soft- *
15  * ware  Foundation;  either version 2,  or (at your option) any later ver- *
16  * sion.  GNAT is distributed in the hope that it will be useful, but WITH- *
17  * OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY *
18  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License *
19  * for  more details.  You should have  received  a copy of the GNU General *
20  * Public License  distributed with GNAT;  see file COPYING.  If not, write *
21  * to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, *
22  * MA 02111-1307, USA.                                                      *
23  *                                                                          *
24  * GNAT was originally developed  by the GNAT team at  New York University. *
25  * It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). *
26  *                                                                          *
27  ****************************************************************************/
28
29 #include "config.h"
30 #include "system.h"
31
32 #if defined (__EMX__) || defined (MSDOS)
33 #include <process.h>
34 #endif
35 #include "adaint.h"
36
37 #ifdef VMS
38 #ifdef exit
39 #undef exit
40 #endif
41 #define exit __posix_exit
42 #endif
43
44 /* These can be set by command line arguments */
45 char *binder_path = 0;
46 char *linker_path = 0;
47 char *exec_file_name = 0;
48 char *ali_file_name = 0;
49 #define BIND_ARG_MAX 512
50 char *bind_args[BIND_ARG_MAX];
51 int  bind_arg_index = -1;
52 #ifdef MSDOS
53 char *coff2exe_path = 0;
54 char *coff2exe_args[] = {(char *) 0, (char *) 0};
55 char *del_command = 0;
56 #endif
57 int  verbose      = 0;
58 int  o_present    = 0;
59 int  g_present    = 0;
60
61 int  link_arg_max = -1;
62 char **link_args = (char **) 0;
63 int  link_arg_index = -1;
64
65 char *gcc_B_arg = 0;
66
67 #ifndef DIR_SEPARATOR
68 #if defined (__EMX__)
69 #define DIR_SEPARATOR '\\'
70 #else
71 #define DIR_SEPARATOR '/'
72 #endif
73 #endif
74
75 static int linkonly = 0;
76
77 static void addarg              PARAMS ((char *));
78 static void process_args        PARAMS ((int *, char *[]));
79 \f
80 static void
81 addarg (str)
82      char *str;
83 {
84   int i;
85
86   if (++link_arg_index >= link_arg_max)
87     {
88       char **new_link_args
89         = (char **) xcalloc (link_arg_max + 1000, sizeof (char *));
90
91       for (i = 0; i <= link_arg_max; i++)
92         new_link_args[i] = link_args[i];
93
94       if (link_args)
95         free (link_args);
96
97       link_arg_max += 1000;
98       link_args = new_link_args;
99     }
100
101   link_args[link_arg_index] = str;
102 }
103
104 static void
105 process_args (p_argc, argv)
106      int *p_argc;
107      char *argv[];
108 {
109   int i, j;
110
111   for (i = 1; i < *p_argc; i++)
112     {
113       /* -I is passed on to gnatbind */
114       if (! strncmp( argv[i], "-I", 2))
115         {
116           bind_arg_index += 1;
117           if (bind_arg_index >= BIND_ARG_MAX)
118             {
119               fprintf (stderr, "Too many arguments to gnatbind\n");
120               exit (-1);
121       }
122
123           bind_args[bind_arg_index] = argv[i];
124         }
125
126       /* -B is passed on to gcc */
127       if (! strncmp (argv[i], "-B", 2))
128         gcc_B_arg = argv[i];
129
130       /* -v turns on verbose option here and is passed on to gcc */
131
132       if (! strcmp (argv[i], "-v"))
133         verbose = 1;
134
135       if (! strcmp (argv[i], "-o"))
136         {
137           o_present = 1;
138           exec_file_name = argv[i + 1];
139         }
140
141       if (! strcmp (argv[i], "-g"))
142         g_present = 1;
143
144       if (! strcmp (argv[i], "-gnatbind"))
145         {
146           /* Explicit naming of binder.  Grab the value then remove the
147              two arguments from the argument list. */
148           if ( i + 1 >= *p_argc )
149             {
150               fprintf (stderr, "Missing argument for -gnatbind\n");
151               exit (1);
152             }
153
154           binder_path = __gnat_locate_exec (argv[i + 1], (char *) ".");
155           if (!binder_path)
156             {
157               fprintf (stderr, "Could not locate binder: %s\n", argv[i + 1]);
158               exit (1);
159             }
160
161           for (j = i + 2; j < *p_argc; j++)
162             argv[j - 2] = argv[j];
163
164           (*p_argc) -= 2;
165           i--;
166         }
167
168     else if (! strcmp (argv[i], "-linkonly"))
169       {
170         /* Don't call the binder. Set the flag and then remove the
171            argument from the argument list. */
172         linkonly = 1;
173         for (j = i + 1; j < *p_argc; j++)
174           argv[j - 1] = argv[j];
175
176         *p_argc -= 1;
177         i--;
178       }
179
180     else if (! strcmp (argv[i], "-gnatlink"))
181       {
182         /* Explicit naming of binder.  Grab the value then remove the
183            two arguments from the argument list. */
184         if (i + 1 >= *p_argc)
185           {
186             fprintf (stderr, "Missing argument for -gnatlink\n");
187             exit (1);
188           }
189
190         linker_path = __gnat_locate_exec (argv[i + 1], (char *) ".");
191         if (!linker_path)
192           {
193             fprintf (stderr, "Could not locate linker: %s\n", argv[i + 1]);
194             exit (1);
195           }
196
197         for (j = i + 2; j < *p_argc; j++)
198           argv[j - 2] = argv[j];
199         *p_argc -= 2;
200         i--;
201       }
202     }
203 }
204 extern int main PARAMS ((int, char **));
205
206 int
207 main (argc, argv)
208      int argc;
209      char **argv;
210 {
211   int i, j;
212   int done_an_ali = 0;
213   int retcode;
214 #ifdef VMS
215   /* Warning: getenv only retrieves the first directory in VAXC$PATH */
216   char *pathval =
217     xstrdup (__gnat_to_canonical_dir_spec (getenv ("VAXC$PATH"), 0));
218 #else
219   char *pathval = getenv ("PATH");
220 #endif
221   char *spawn_args[5];
222   int  spawn_index = 0;
223
224 #if defined (__EMX__) || defined(MSDOS)
225   char *tmppathval = malloc (strlen (pathval) + 3);
226   strcpy (tmppathval, ".;");
227   pathval = strcat (tmppathval, pathval);
228 #endif
229
230   process_args (&argc , argv);
231
232   if (argc == 1)
233     {
234       fprintf
235         (stdout,
236          "Usage: %s 'name'.ali\n", argv[0]);
237       fprintf
238         (stdout,
239          "             [-o exec_name]        -- by default it is 'name'\n");
240       fprintf
241         (stdout,
242          "             [-v]                  -- verbose mode\n");
243       fprintf
244         (stdout,
245          "             [-linkonly]           -- doesn't call binder\n");
246       fprintf
247         (stdout,
248          "             [-gnatbind name]      -- full name for gnatbind\n");
249       fprintf
250         (stdout,
251          "             [-gnatlink name]      -- full name for linker (gcc)\n");
252       fprintf
253         (stdout,
254          "             [list of objects]     -- non Ada binaries\n");
255       fprintf
256         (stdout,
257          "             [linker options]      -- other options for linker\n");
258       exit (1);
259     }
260
261   if (!binder_path && !linkonly)
262     binder_path = __gnat_locate_exec ((char *) "gnatbind", pathval);
263
264   if (!binder_path && !linkonly)
265     {
266       fprintf (stderr, "Couldn't locate gnatbind\n");
267       exit (1);
268     }
269
270   if (!linker_path)
271     linker_path = __gnat_locate_exec ((char *) "gnatlink", pathval);
272     if (!linker_path)
273       {
274         fprintf (stderr, "Couldn't locate gnatlink\n");
275         exit (1);
276       }
277
278 #ifdef MSDOS
279   coff2exe_path = __gnat_locate_regular_file ("coff2exe.bat", pathval);
280   if (!coff2exe_path)
281     {
282       fprintf (stderr, "Couldn't locate %s\n", "coff2exe.bat");
283       exit (1);
284     }
285   else
286     coff2exe_args[0] = coff2exe_path;
287 #endif
288
289   addarg (linker_path);
290
291   for (i = 1; i < argc; i++)
292     {
293       int arg_len = strlen (argv[i]);
294
295       if (arg_len > 4 && ! strcmp (&argv[i][arg_len - 4], ".ali"))
296         {
297           if (done_an_ali)
298             {
299               fprintf (stderr, 
300                        "Sorry - cannot handle more than one ALI file\n");
301               exit (1);
302             }
303
304           done_an_ali = 1;
305
306           if (__gnat_is_regular_file (argv[i]))
307             {
308               ali_file_name = argv[i];
309               if (!linkonly)
310                 {
311                   /* Run gnatbind */
312                   spawn_index = 0;
313                   spawn_args[spawn_index++] = binder_path;
314                   spawn_args[spawn_index++] = ali_file_name;
315                   for (j = 0 ; j <= bind_arg_index ; j++ )
316                     spawn_args[spawn_index++] = bind_args[j];
317                   spawn_args[spawn_index] = 0;
318
319                   if (verbose)
320                     {
321                       int i;
322                       for (i = 0; i < 2; i++)
323                         printf ("%s ", spawn_args[i]);
324
325                       putchar ('\n');
326                     }
327
328                   retcode = __gnat_portable_spawn (spawn_args);
329                   if (retcode != 0)
330                     exit (retcode);
331                 }
332             }
333           else 
334             addarg (argv[i]);
335         }
336 #ifdef MSDOS
337       else if (!strcmp (argv[i], "-o"))
338         {
339           addarg (argv[i]);
340           if (i < argc)
341             i++;
342
343           {
344             char *ptr = strstr (argv[i], ".exe");
345
346             arg_len = strlen (argv[i]);
347             coff2exe_args[1] = malloc (arg_len + 1);
348             strcpy (coff2exe_args[1], argv[i]);
349             if (ptr != NULL && strlen (ptr) == 4)
350               coff2exe_args[1][arg_len-4] = 0;
351
352             addarg (coff2exe_args[1]);
353           }
354         }
355 #endif
356       else
357         addarg (argv[i]);
358     }
359
360   if (! done_an_ali)
361     {
362       fprintf (stderr, "No \".ali\" file specified\n");
363       exit (1);
364     }
365
366   addarg (ali_file_name);
367   addarg (NULL);
368
369   if (verbose)
370     {
371       int i;
372
373       for (i = 0; i < link_arg_index; i++)
374         printf ("%s ", link_args[i]);
375
376       putchar ('\n');
377     }
378
379   retcode = __gnat_portable_spawn (link_args);
380   if (retcode != 0)
381     exit (retcode);
382
383 #ifdef MSDOS
384   retcode = __gnat_portable_spawn (coff2exe_args);
385   if (retcode != 0)
386     exit (retcode);
387
388   if (!g_present)
389     {
390       del_command = malloc (strlen (coff2exe_args[1]) + 5);
391       sprintf (del_command, "del %s", coff2exe_args[1]);
392       retcode = system (del_command);
393     }
394 #endif
395
396   exit(0);
397 }