OSDN Git Service

3cccc3d0304e02fd85d56385c85f00d2002e9433
[pf3gnuchains/gcc-fork.git] / libgfortran / runtime / main.c
1 /* Copyright (C) 2002-2003, 2005, 2007, 2009 Free Software Foundation, Inc.
2    Contributed by Andy Vaught and Paul Brook <paul@nowt.org>
3
4 This file is part of the GNU Fortran 95 runtime library (libgfortran).
5
6 Libgfortran is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 Libgfortran is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
19
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 <http://www.gnu.org/licenses/>.  */
24
25 #include "libgfortran.h"
26 #include <stdlib.h>
27 #include <string.h>
28 #include <limits.h>
29
30
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34
35 /* Stupid function to be sure the constructor is always linked in, even
36    in the case of static linking.  See PR libfortran/22298 for details.  */
37 void
38 stupid_function_name_for_static_linking (void)
39 {
40   return;
41 }
42
43 /* This will be 0 for little-endian
44    machines and 1 for big-endian machines.  */
45 int big_endian = 0;
46
47
48 /* Figure out endianness for this machine.  */
49
50 static void
51 determine_endianness (void)
52 {
53   union
54   {
55     GFC_LOGICAL_8 l8;
56     GFC_LOGICAL_4 l4[2];
57   } u;
58
59   u.l8 = 1;
60   if (u.l4[0])
61     big_endian = 0;
62   else if (u.l4[1])
63     big_endian = 1;
64   else
65     runtime_error ("Unable to determine machine endianness");
66 }
67
68
69 static int argc_save;
70 static char **argv_save;
71
72 /* Set the saved values of the command line arguments.  */
73
74 void
75 set_args (int argc, char **argv)
76 {
77   argc_save = argc;
78   argv_save = argv;
79 }
80
81 /* Retrieve the saved values of the command line arguments.  */
82
83 void
84 get_args (int *argc, char ***argv)
85 {
86   *argc = argc_save;
87   *argv = argv_save;
88 }
89
90
91 static const char *exe_path;
92 static int please_free_exe_path_when_done;
93
94 /* Save the path under which the program was called, for use in the
95    backtrace routines.  */
96 void
97 store_exe_path (const char * argv0)
98 {
99 #ifndef PATH_MAX
100 #define PATH_MAX 1024
101 #endif
102
103 #ifndef DIR_SEPARATOR   
104 #define DIR_SEPARATOR '/'
105 #endif
106
107   char buf[PATH_MAX], *cwd, *path;
108
109   /* On the simulator argv is not set.  */
110   if (argv0 == NULL || argv0[0] == '/')
111     {
112       exe_path = argv0;
113       please_free_exe_path_when_done = 0;
114       return;
115     }
116
117   memset (buf, 0, sizeof (buf));
118 #ifdef HAVE_GETCWD
119   cwd = getcwd (buf, sizeof (buf));
120 #else
121   cwd = "";
122 #endif
123
124   /* exe_path will be cwd + "/" + argv[0] + "\0" */
125   path = malloc (strlen (cwd) + 1 + strlen (argv0) + 1);
126   sprintf (path, "%s%c%s", cwd, DIR_SEPARATOR, argv0);
127   exe_path = path;
128   please_free_exe_path_when_done = 1;
129 }
130
131 /* Return the full path of the executable.  */
132 char *
133 full_exe_path (void)
134 {
135   return (char *) exe_path;
136 }
137
138 /* Initialize the runtime library.  */
139
140 static void __attribute__((constructor))
141 init (void)
142 {
143   /* Figure out the machine endianness.  */
144   determine_endianness ();
145
146   /* Must be first */
147   init_variables ();
148
149   init_units ();
150   set_fpu ();
151   init_compile_options ();
152
153 #ifdef DEBUG
154   /* Check for special command lines.  */
155
156   if (argc > 1 && strcmp (argv[1], "--help") == 0)
157     show_variables ();
158
159   /* if (argc > 1 && strcmp(argv[1], "--resume") == 0) resume();  */
160 #endif
161
162   random_seed_i4 (NULL, NULL, NULL);
163 }
164
165
166 /* Cleanup the runtime library.  */
167
168 static void __attribute__((destructor))
169 cleanup (void)
170 {
171   close_units ();
172   
173   if (please_free_exe_path_when_done)
174     free ((char *) exe_path);
175 }