2011-02-22 Tobias Burnus <burnus@net-b.de>
[official-gcc.git] / libgfortran / io / intrinsics.c
blobf48bd777456d60ba16bb2d7d21612a8034082476
1 /* Implementation of the FGET, FGETC, FPUT, FPUTC, FLUSH
2 FTELL, TTYNAM and ISATTY intrinsics.
3 Copyright (C) 2005, 2007, 2009, 2010, 2011 Free Software
4 Foundation, Inc.
6 This file is part of the GNU Fortran runtime library (libgfortran).
8 Libgfortran is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public
10 License as published by the Free Software Foundation; either
11 version 3 of the License, or (at your option) any later version.
13 Libgfortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
27 #include "io.h"
28 #include "fbuf.h"
29 #include "unix.h"
31 #ifdef HAVE_STDLIB_H
32 #include <stdlib.h>
33 #endif
35 #include <string.h>
37 static const int five = 5;
38 static const int six = 6;
40 extern int PREFIX(fgetc) (const int *, char *, gfc_charlen_type);
41 export_proto_np(PREFIX(fgetc));
43 int
44 PREFIX(fgetc) (const int * unit, char * c, gfc_charlen_type c_len)
46 int ret;
47 gfc_unit * u = find_unit (*unit);
49 if (u == NULL)
50 return -1;
52 fbuf_reset (u);
53 if (u->mode == WRITING)
55 sflush (u->s);
56 u->mode = READING;
59 memset (c, ' ', c_len);
60 ret = sread (u->s, c, 1);
61 unlock_unit (u);
63 if (ret < 0)
64 return ret;
66 if (ret != 1)
67 return -1;
68 else
69 return 0;
73 #define FGETC_SUB(kind) \
74 extern void fgetc_i ## kind ## _sub \
75 (const int *, char *, GFC_INTEGER_ ## kind *, gfc_charlen_type); \
76 export_proto(fgetc_i ## kind ## _sub); \
77 void fgetc_i ## kind ## _sub \
78 (const int * unit, char * c, GFC_INTEGER_ ## kind * st, gfc_charlen_type c_len) \
79 { if (st != NULL) \
80 *st = PREFIX(fgetc) (unit, c, c_len); \
81 else \
82 PREFIX(fgetc) (unit, c, c_len); }
84 FGETC_SUB(1)
85 FGETC_SUB(2)
86 FGETC_SUB(4)
87 FGETC_SUB(8)
90 extern int PREFIX(fget) (char *, gfc_charlen_type);
91 export_proto_np(PREFIX(fget));
93 int
94 PREFIX(fget) (char * c, gfc_charlen_type c_len)
96 return PREFIX(fgetc) (&five, c, c_len);
100 #define FGET_SUB(kind) \
101 extern void fget_i ## kind ## _sub \
102 (char *, GFC_INTEGER_ ## kind *, gfc_charlen_type); \
103 export_proto(fget_i ## kind ## _sub); \
104 void fget_i ## kind ## _sub \
105 (char * c, GFC_INTEGER_ ## kind * st, gfc_charlen_type c_len) \
106 { if (st != NULL) \
107 *st = PREFIX(fgetc) (&five, c, c_len); \
108 else \
109 PREFIX(fgetc) (&five, c, c_len); }
111 FGET_SUB(1)
112 FGET_SUB(2)
113 FGET_SUB(4)
114 FGET_SUB(8)
118 extern int PREFIX(fputc) (const int *, char *, gfc_charlen_type);
119 export_proto_np(PREFIX(fputc));
122 PREFIX(fputc) (const int * unit, char * c,
123 gfc_charlen_type c_len __attribute__((unused)))
125 ssize_t s;
126 gfc_unit * u = find_unit (*unit);
128 if (u == NULL)
129 return -1;
131 fbuf_reset (u);
132 if (u->mode == READING)
134 sflush (u->s);
135 u->mode = WRITING;
138 s = swrite (u->s, c, 1);
139 unlock_unit (u);
140 if (s < 0)
141 return -1;
142 return 0;
146 #define FPUTC_SUB(kind) \
147 extern void fputc_i ## kind ## _sub \
148 (const int *, char *, GFC_INTEGER_ ## kind *, gfc_charlen_type); \
149 export_proto(fputc_i ## kind ## _sub); \
150 void fputc_i ## kind ## _sub \
151 (const int * unit, char * c, GFC_INTEGER_ ## kind * st, gfc_charlen_type c_len) \
152 { if (st != NULL) \
153 *st = PREFIX(fputc) (unit, c, c_len); \
154 else \
155 PREFIX(fputc) (unit, c, c_len); }
157 FPUTC_SUB(1)
158 FPUTC_SUB(2)
159 FPUTC_SUB(4)
160 FPUTC_SUB(8)
163 extern int PREFIX(fput) (char *, gfc_charlen_type);
164 export_proto_np(PREFIX(fput));
167 PREFIX(fput) (char * c, gfc_charlen_type c_len)
169 return PREFIX(fputc) (&six, c, c_len);
173 #define FPUT_SUB(kind) \
174 extern void fput_i ## kind ## _sub \
175 (char *, GFC_INTEGER_ ## kind *, gfc_charlen_type); \
176 export_proto(fput_i ## kind ## _sub); \
177 void fput_i ## kind ## _sub \
178 (char * c, GFC_INTEGER_ ## kind * st, gfc_charlen_type c_len) \
179 { if (st != NULL) \
180 *st = PREFIX(fputc) (&six, c, c_len); \
181 else \
182 PREFIX(fputc) (&six, c, c_len); }
184 FPUT_SUB(1)
185 FPUT_SUB(2)
186 FPUT_SUB(4)
187 FPUT_SUB(8)
190 /* SUBROUTINE FLUSH(UNIT)
191 INTEGER, INTENT(IN), OPTIONAL :: UNIT */
193 extern void flush_i4 (GFC_INTEGER_4 *);
194 export_proto(flush_i4);
196 void
197 flush_i4 (GFC_INTEGER_4 *unit)
199 gfc_unit *us;
201 /* flush all streams */
202 if (unit == NULL)
203 flush_all_units ();
204 else
206 us = find_unit (*unit);
207 if (us != NULL)
209 sflush (us->s);
210 unlock_unit (us);
216 extern void flush_i8 (GFC_INTEGER_8 *);
217 export_proto(flush_i8);
219 void
220 flush_i8 (GFC_INTEGER_8 *unit)
222 gfc_unit *us;
224 /* flush all streams */
225 if (unit == NULL)
226 flush_all_units ();
227 else
229 us = find_unit (*unit);
230 if (us != NULL)
232 sflush (us->s);
233 unlock_unit (us);
238 /* FSEEK intrinsic */
240 extern void fseek_sub (int *, GFC_IO_INT *, int *, int *);
241 export_proto(fseek_sub);
243 void
244 fseek_sub (int * unit, GFC_IO_INT * offset, int * whence, int * status)
246 gfc_unit * u = find_unit (*unit);
247 ssize_t result = -1;
249 if (u != NULL && is_seekable(u->s))
251 result = sseek(u->s, *offset, *whence);
253 unlock_unit (u);
256 if (status)
257 *status = (result < 0 ? -1 : 0);
262 /* FTELL intrinsic */
264 static gfc_offset
265 gf_ftell (int unit)
267 gfc_unit * u = find_unit (unit);
268 if (u == NULL)
269 return -1;
270 int pos = fbuf_reset (u);
271 if (pos != 0)
272 sseek (u->s, pos, SEEK_CUR);
273 gfc_offset ret = stell (u->s);
274 unlock_unit (u);
275 return ret;
278 extern size_t PREFIX(ftell) (int *);
279 export_proto_np(PREFIX(ftell));
281 size_t
282 PREFIX(ftell) (int * unit)
284 return gf_ftell (*unit);
287 #define FTELL_SUB(kind) \
288 extern void ftell_i ## kind ## _sub (int *, GFC_INTEGER_ ## kind *); \
289 export_proto(ftell_i ## kind ## _sub); \
290 void \
291 ftell_i ## kind ## _sub (int * unit, GFC_INTEGER_ ## kind * offset) \
293 *offset = gf_ftell (*unit); \
296 FTELL_SUB(1)
297 FTELL_SUB(2)
298 FTELL_SUB(4)
299 FTELL_SUB(8)
303 /* LOGICAL FUNCTION ISATTY(UNIT)
304 INTEGER, INTENT(IN) :: UNIT */
306 extern GFC_LOGICAL_4 isatty_l4 (int *);
307 export_proto(isatty_l4);
309 GFC_LOGICAL_4
310 isatty_l4 (int *unit)
312 gfc_unit *u;
313 GFC_LOGICAL_4 ret = 0;
315 u = find_unit (*unit);
316 if (u != NULL)
318 ret = (GFC_LOGICAL_4) stream_isatty (u->s);
319 unlock_unit (u);
321 return ret;
325 extern GFC_LOGICAL_8 isatty_l8 (int *);
326 export_proto(isatty_l8);
328 GFC_LOGICAL_8
329 isatty_l8 (int *unit)
331 gfc_unit *u;
332 GFC_LOGICAL_8 ret = 0;
334 u = find_unit (*unit);
335 if (u != NULL)
337 ret = (GFC_LOGICAL_8) stream_isatty (u->s);
338 unlock_unit (u);
340 return ret;
344 /* SUBROUTINE TTYNAM(UNIT,NAME)
345 INTEGER,SCALAR,INTENT(IN) :: UNIT
346 CHARACTER,SCALAR,INTENT(OUT) :: NAME */
348 extern void ttynam_sub (int *, char *, gfc_charlen_type);
349 export_proto(ttynam_sub);
351 void
352 ttynam_sub (int *unit, char * name, gfc_charlen_type name_len)
354 gfc_unit *u;
355 int nlen;
356 int err = 1;
358 u = find_unit (*unit);
359 if (u != NULL)
361 err = stream_ttyname (u->s, name, name_len);
362 if (err == 0)
364 nlen = strlen (name);
365 memset (&name[nlen], ' ', name_len - nlen);
368 unlock_unit (u);
370 if (err != 0)
371 memset (name, ' ', name_len);
375 extern void ttynam (char **, gfc_charlen_type *, int);
376 export_proto(ttynam);
378 void
379 ttynam (char ** name, gfc_charlen_type * name_len, int unit)
381 gfc_unit *u;
383 u = find_unit (unit);
384 if (u != NULL)
386 *name = get_mem (TTY_NAME_MAX);
387 int err = stream_ttyname (u->s, *name, TTY_NAME_MAX);
388 if (err == 0)
390 *name_len = strlen (*name);
391 unlock_unit (u);
392 return;
394 free (*name);
395 unlock_unit (u);
398 *name_len = 0;
399 *name = NULL;