OSDN Git Service

./:
[pf3gnuchains/gcc-fork.git] / gcc / fortran / misc.c
1 /* Miscellaneous stuff that doesn't fit anywhere else.
2    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
3    Free Software Foundation, Inc.
4    Contributed by Andy Vaught
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "gfortran.h"
25
26 /* Get a block of memory.  Many callers assume that the memory we
27    return is zeroed.  */
28
29 void *
30 gfc_getmem (size_t n)
31 {
32   void *p;
33
34   if (n == 0)
35     return NULL;
36
37   p = xmalloc (n);
38   if (p == NULL)
39     gfc_fatal_error ("Out of memory-- malloc() failed");
40   memset (p, 0, n);
41   return p;
42 }
43
44
45 /* gfortran.h defines free to something that triggers a syntax error,
46    but we need free() here.  */
47
48 #define temp free
49 #undef free
50
51 void
52 gfc_free (void *p)
53 {
54   if (p != NULL)
55     free (p);
56 }
57
58 #define free temp
59 #undef temp
60
61
62 /* Get terminal width.  */
63
64 int
65 gfc_terminal_width (void)
66 {
67   return 80;
68 }
69
70
71 /* Initialize a typespec to unknown.  */
72
73 void
74 gfc_clear_ts (gfc_typespec *ts)
75 {
76   ts->type = BT_UNKNOWN;
77   ts->kind = 0;
78   ts->derived = NULL;
79   ts->cl = NULL;
80   /* flag that says if the type is C interoperable */
81   ts->is_c_interop = 0;
82   /* says what f90 type the C kind interops with */
83   ts->f90_type = BT_UNKNOWN;
84   /* flag that says whether it's from iso_c_binding or not */
85   ts->is_iso_c = 0;
86 }
87
88
89 /* Open a file for reading.  */
90
91 FILE *
92 gfc_open_file (const char *name)
93 {
94   struct stat statbuf;
95
96   if (!*name)
97     return stdin;
98
99   if (stat (name, &statbuf) < 0)
100     return NULL;
101
102   if (!S_ISREG (statbuf.st_mode))
103     return NULL;
104
105   return fopen (name, "r");
106 }
107
108
109 /* Return a string for each type.  */
110
111 const char *
112 gfc_basic_typename (bt type)
113 {
114   const char *p;
115
116   switch (type)
117     {
118     case BT_INTEGER:
119       p = "INTEGER";
120       break;
121     case BT_REAL:
122       p = "REAL";
123       break;
124     case BT_COMPLEX:
125       p = "COMPLEX";
126       break;
127     case BT_LOGICAL:
128       p = "LOGICAL";
129       break;
130     case BT_CHARACTER:
131       p = "CHARACTER";
132       break;
133     case BT_HOLLERITH:
134       p = "HOLLERITH";
135       break;
136     case BT_DERIVED:
137       p = "DERIVED";
138       break;
139     case BT_PROCEDURE:
140       p = "PROCEDURE";
141       break;
142     case BT_UNKNOWN:
143       p = "UNKNOWN";
144       break;
145     default:
146       gfc_internal_error ("gfc_basic_typename(): Undefined type");
147     }
148
149   return p;
150 }
151
152
153 /* Return a string describing the type and kind of a typespec.  Because
154    we return alternating buffers, this subroutine can appear twice in
155    the argument list of a single statement.  */
156
157 const char *
158 gfc_typename (gfc_typespec *ts)
159 {
160   static char buffer1[GFC_MAX_SYMBOL_LEN + 7];  /* 7 for "TYPE()" + '\0'.  */
161   static char buffer2[GFC_MAX_SYMBOL_LEN + 7];
162   static int flag = 0;
163   char *buffer;
164
165   buffer = flag ? buffer1 : buffer2;
166   flag = !flag;
167
168   switch (ts->type)
169     {
170     case BT_INTEGER:
171       sprintf (buffer, "INTEGER(%d)", ts->kind);
172       break;
173     case BT_REAL:
174       sprintf (buffer, "REAL(%d)", ts->kind);
175       break;
176     case BT_COMPLEX:
177       sprintf (buffer, "COMPLEX(%d)", ts->kind);
178       break;
179     case BT_LOGICAL:
180       sprintf (buffer, "LOGICAL(%d)", ts->kind);
181       break;
182     case BT_CHARACTER:
183       sprintf (buffer, "CHARACTER(%d)", ts->kind);
184       break;
185     case BT_HOLLERITH:
186       sprintf (buffer, "HOLLERITH");
187       break;
188     case BT_DERIVED:
189       sprintf (buffer, "TYPE(%s)", ts->derived->name);
190       break;
191     case BT_PROCEDURE:
192       strcpy (buffer, "PROCEDURE");
193       break;
194     case BT_UNKNOWN:
195       strcpy (buffer, "UNKNOWN");
196       break;
197     default:
198       gfc_internal_error ("gfc_typename(): Undefined type");
199     }
200
201   return buffer;
202 }
203
204
205 /* Given an mstring array and a code, locate the code in the table,
206    returning a pointer to the string.  */
207
208 const char *
209 gfc_code2string (const mstring *m, int code)
210 {
211   while (m->string != NULL)
212     {
213       if (m->tag == code)
214         return m->string;
215       m++;
216     }
217
218   gfc_internal_error ("gfc_code2string(): Bad code");
219   /* Not reached */
220 }
221
222
223 /* Given an mstring array and a string, returns the value of the tag
224    field.  Returns the final tag if no matches to the string are found.  */
225
226 int
227 gfc_string2code (const mstring *m, const char *string)
228 {
229   for (; m->string != NULL; m++)
230     if (strcmp (m->string, string) == 0)
231       return m->tag;
232
233   return m->tag;
234 }
235
236
237 /* Convert an intent code to a string.  */
238 /* TODO: move to gfortran.h as define.  */
239
240 const char *
241 gfc_intent_string (sym_intent i)
242 {
243   return gfc_code2string (intents, i);
244 }
245
246
247 /***************** Initialization functions ****************/
248
249 /* Top level initialization.  */
250
251 void
252 gfc_init_1 (void)
253 {
254   gfc_error_init_1 ();
255   gfc_scanner_init_1 ();
256   gfc_arith_init_1 ();
257   gfc_intrinsic_init_1 ();
258 }
259
260
261 /* Per program unit initialization.  */
262
263 void
264 gfc_init_2 (void)
265 {
266   gfc_symbol_init_2 ();
267   gfc_module_init_2 ();
268 }
269
270
271 /******************* Destructor functions ******************/
272
273 /* Call all of the top level destructors.  */
274
275 void
276 gfc_done_1 (void)
277 {
278   gfc_scanner_done_1 ();
279   gfc_intrinsic_done_1 ();
280   gfc_arith_done_1 ();
281 }
282
283
284 /* Per program unit destructors.  */
285
286 void
287 gfc_done_2 (void)
288 {
289   gfc_symbol_done_2 ();
290   gfc_module_done_2 ();
291 }
292
293
294 /* Returns the index into the table of C interoperable kinds where the
295    kind with the given name (c_kind_name) was found.  */
296
297 int
298 get_c_kind(const char *c_kind_name, CInteropKind_t kinds_table[])
299 {
300   int index = 0;
301
302   for (index = 0; index < ISOCBINDING_LAST; index++)
303     if (strcmp (kinds_table[index].name, c_kind_name) == 0)
304       return index;
305
306   return ISOCBINDING_INVALID;
307 }