intrinsics.c revision 1.1 1 1.1 mrg /* Implementation of the FGET, FGETC, FPUT, FPUTC, FLUSH
2 1.1 mrg FTELL, TTYNAM and ISATTY intrinsics.
3 1.1 mrg Copyright (C) 2005-2019 Free Software Foundation, Inc.
4 1.1 mrg
5 1.1 mrg This file is part of the GNU Fortran runtime library (libgfortran).
6 1.1 mrg
7 1.1 mrg Libgfortran is free software; you can redistribute it and/or
8 1.1 mrg modify it under the terms of the GNU General Public
9 1.1 mrg License as published by the Free Software Foundation; either
10 1.1 mrg version 3 of the License, or (at your option) any later version.
11 1.1 mrg
12 1.1 mrg Libgfortran is distributed in the hope that it will be useful,
13 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 mrg GNU General Public License for more details.
16 1.1 mrg
17 1.1 mrg Under Section 7 of GPL version 3, you are granted additional
18 1.1 mrg permissions described in the GCC Runtime Library Exception, version
19 1.1 mrg 3.1, as published by the Free Software Foundation.
20 1.1 mrg
21 1.1 mrg You should have received a copy of the GNU General Public License and
22 1.1 mrg a copy of the GCC Runtime Library Exception along with this program;
23 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 1.1 mrg <http://www.gnu.org/licenses/>. */
25 1.1 mrg
26 1.1 mrg #include "io.h"
27 1.1 mrg #include "fbuf.h"
28 1.1 mrg #include "unix.h"
29 1.1 mrg #include <string.h>
30 1.1 mrg
31 1.1 mrg
32 1.1 mrg static const int five = 5;
33 1.1 mrg static const int six = 6;
34 1.1 mrg
35 1.1 mrg extern int PREFIX(fgetc) (const int *, char *, gfc_charlen_type);
36 1.1 mrg export_proto_np(PREFIX(fgetc));
37 1.1 mrg
38 1.1 mrg int
39 1.1 mrg PREFIX(fgetc) (const int *unit, char *c, gfc_charlen_type c_len)
40 1.1 mrg {
41 1.1 mrg int ret;
42 1.1 mrg gfc_unit *u = find_unit (*unit);
43 1.1 mrg
44 1.1 mrg if (u == NULL)
45 1.1 mrg return -1;
46 1.1 mrg
47 1.1 mrg fbuf_reset (u);
48 1.1 mrg if (u->mode == WRITING)
49 1.1 mrg {
50 1.1 mrg sflush (u->s);
51 1.1 mrg u->mode = READING;
52 1.1 mrg }
53 1.1 mrg
54 1.1 mrg memset (c, ' ', c_len);
55 1.1 mrg ret = sread (u->s, c, 1);
56 1.1 mrg unlock_unit (u);
57 1.1 mrg
58 1.1 mrg if (ret < 0)
59 1.1 mrg return ret;
60 1.1 mrg
61 1.1 mrg if (ret != 1)
62 1.1 mrg return -1;
63 1.1 mrg else
64 1.1 mrg return 0;
65 1.1 mrg }
66 1.1 mrg
67 1.1 mrg
68 1.1 mrg #define FGETC_SUB(kind) \
69 1.1 mrg extern void fgetc_i ## kind ## _sub \
70 1.1 mrg (const int *, char *, GFC_INTEGER_ ## kind *, gfc_charlen_type); \
71 1.1 mrg export_proto(fgetc_i ## kind ## _sub); \
72 1.1 mrg void fgetc_i ## kind ## _sub \
73 1.1 mrg (const int *unit, char *c, GFC_INTEGER_ ## kind *st, gfc_charlen_type c_len) \
74 1.1 mrg { if (st != NULL) \
75 1.1 mrg *st = PREFIX(fgetc) (unit, c, c_len); \
76 1.1 mrg else \
77 1.1 mrg PREFIX(fgetc) (unit, c, c_len); }
78 1.1 mrg
79 1.1 mrg FGETC_SUB(1)
80 1.1 mrg FGETC_SUB(2)
81 1.1 mrg FGETC_SUB(4)
82 1.1 mrg FGETC_SUB(8)
83 1.1 mrg
84 1.1 mrg
85 1.1 mrg extern int PREFIX(fget) (char *, gfc_charlen_type);
86 1.1 mrg export_proto_np(PREFIX(fget));
87 1.1 mrg
88 1.1 mrg int
89 1.1 mrg PREFIX(fget) (char *c, gfc_charlen_type c_len)
90 1.1 mrg {
91 1.1 mrg return PREFIX(fgetc) (&five, c, c_len);
92 1.1 mrg }
93 1.1 mrg
94 1.1 mrg
95 1.1 mrg #define FGET_SUB(kind) \
96 1.1 mrg extern void fget_i ## kind ## _sub \
97 1.1 mrg (char *, GFC_INTEGER_ ## kind *, gfc_charlen_type); \
98 1.1 mrg export_proto(fget_i ## kind ## _sub); \
99 1.1 mrg void fget_i ## kind ## _sub \
100 1.1 mrg (char *c, GFC_INTEGER_ ## kind *st, gfc_charlen_type c_len) \
101 1.1 mrg { if (st != NULL) \
102 1.1 mrg *st = PREFIX(fgetc) (&five, c, c_len); \
103 1.1 mrg else \
104 1.1 mrg PREFIX(fgetc) (&five, c, c_len); }
105 1.1 mrg
106 1.1 mrg FGET_SUB(1)
107 1.1 mrg FGET_SUB(2)
108 1.1 mrg FGET_SUB(4)
109 1.1 mrg FGET_SUB(8)
110 1.1 mrg
111 1.1 mrg
112 1.1 mrg
113 1.1 mrg extern int PREFIX(fputc) (const int *, char *, gfc_charlen_type);
114 1.1 mrg export_proto_np(PREFIX(fputc));
115 1.1 mrg
116 1.1 mrg int
117 1.1 mrg PREFIX(fputc) (const int *unit, char *c,
118 1.1 mrg gfc_charlen_type c_len __attribute__((unused)))
119 1.1 mrg {
120 1.1 mrg ssize_t s;
121 1.1 mrg gfc_unit *u = find_unit (*unit);
122 1.1 mrg
123 1.1 mrg if (u == NULL)
124 1.1 mrg return -1;
125 1.1 mrg
126 1.1 mrg fbuf_reset (u);
127 1.1 mrg if (u->mode == READING)
128 1.1 mrg {
129 1.1 mrg sflush (u->s);
130 1.1 mrg u->mode = WRITING;
131 1.1 mrg }
132 1.1 mrg
133 1.1 mrg s = swrite (u->s, c, 1);
134 1.1 mrg unlock_unit (u);
135 1.1 mrg if (s < 0)
136 1.1 mrg return -1;
137 1.1 mrg return 0;
138 1.1 mrg }
139 1.1 mrg
140 1.1 mrg
141 1.1 mrg #define FPUTC_SUB(kind) \
142 1.1 mrg extern void fputc_i ## kind ## _sub \
143 1.1 mrg (const int *, char *, GFC_INTEGER_ ## kind *, gfc_charlen_type); \
144 1.1 mrg export_proto(fputc_i ## kind ## _sub); \
145 1.1 mrg void fputc_i ## kind ## _sub \
146 1.1 mrg (const int *unit, char *c, GFC_INTEGER_ ## kind *st, gfc_charlen_type c_len) \
147 1.1 mrg { if (st != NULL) \
148 1.1 mrg *st = PREFIX(fputc) (unit, c, c_len); \
149 1.1 mrg else \
150 1.1 mrg PREFIX(fputc) (unit, c, c_len); }
151 1.1 mrg
152 1.1 mrg FPUTC_SUB(1)
153 1.1 mrg FPUTC_SUB(2)
154 1.1 mrg FPUTC_SUB(4)
155 1.1 mrg FPUTC_SUB(8)
156 1.1 mrg
157 1.1 mrg
158 1.1 mrg extern int PREFIX(fput) (char *, gfc_charlen_type);
159 1.1 mrg export_proto_np(PREFIX(fput));
160 1.1 mrg
161 1.1 mrg int
162 1.1 mrg PREFIX(fput) (char *c, gfc_charlen_type c_len)
163 1.1 mrg {
164 1.1 mrg return PREFIX(fputc) (&six, c, c_len);
165 1.1 mrg }
166 1.1 mrg
167 1.1 mrg
168 1.1 mrg #define FPUT_SUB(kind) \
169 1.1 mrg extern void fput_i ## kind ## _sub \
170 1.1 mrg (char *, GFC_INTEGER_ ## kind *, gfc_charlen_type); \
171 1.1 mrg export_proto(fput_i ## kind ## _sub); \
172 1.1 mrg void fput_i ## kind ## _sub \
173 1.1 mrg (char *c, GFC_INTEGER_ ## kind *st, gfc_charlen_type c_len) \
174 1.1 mrg { if (st != NULL) \
175 1.1 mrg *st = PREFIX(fputc) (&six, c, c_len); \
176 1.1 mrg else \
177 1.1 mrg PREFIX(fputc) (&six, c, c_len); }
178 1.1 mrg
179 1.1 mrg FPUT_SUB(1)
180 1.1 mrg FPUT_SUB(2)
181 1.1 mrg FPUT_SUB(4)
182 1.1 mrg FPUT_SUB(8)
183 1.1 mrg
184 1.1 mrg
185 1.1 mrg /* SUBROUTINE FLUSH(UNIT)
186 1.1 mrg INTEGER, INTENT(IN), OPTIONAL :: UNIT */
187 1.1 mrg
188 1.1 mrg extern void flush_i4 (GFC_INTEGER_4 *);
189 1.1 mrg export_proto(flush_i4);
190 1.1 mrg
191 1.1 mrg void
192 1.1 mrg flush_i4 (GFC_INTEGER_4 *unit)
193 1.1 mrg {
194 1.1 mrg gfc_unit *us;
195 1.1 mrg
196 1.1 mrg /* flush all streams */
197 1.1 mrg if (unit == NULL)
198 1.1 mrg flush_all_units ();
199 1.1 mrg else
200 1.1 mrg {
201 1.1 mrg us = find_unit (*unit);
202 1.1 mrg if (us != NULL)
203 1.1 mrg {
204 1.1 mrg sflush (us->s);
205 1.1 mrg unlock_unit (us);
206 1.1 mrg }
207 1.1 mrg }
208 1.1 mrg }
209 1.1 mrg
210 1.1 mrg
211 1.1 mrg extern void flush_i8 (GFC_INTEGER_8 *);
212 1.1 mrg export_proto(flush_i8);
213 1.1 mrg
214 1.1 mrg void
215 1.1 mrg flush_i8 (GFC_INTEGER_8 *unit)
216 1.1 mrg {
217 1.1 mrg gfc_unit *us;
218 1.1 mrg
219 1.1 mrg /* flush all streams */
220 1.1 mrg if (unit == NULL)
221 1.1 mrg flush_all_units ();
222 1.1 mrg else
223 1.1 mrg {
224 1.1 mrg us = find_unit (*unit);
225 1.1 mrg if (us != NULL)
226 1.1 mrg {
227 1.1 mrg sflush (us->s);
228 1.1 mrg unlock_unit (us);
229 1.1 mrg }
230 1.1 mrg }
231 1.1 mrg }
232 1.1 mrg
233 1.1 mrg /* FSEEK intrinsic */
234 1.1 mrg
235 1.1 mrg extern void fseek_sub (int *, GFC_IO_INT *, int *, int *);
236 1.1 mrg export_proto(fseek_sub);
237 1.1 mrg
238 1.1 mrg void
239 1.1 mrg fseek_sub (int *unit, GFC_IO_INT *offset, int *whence, int *status)
240 1.1 mrg {
241 1.1 mrg gfc_unit *u = find_unit (*unit);
242 1.1 mrg ssize_t result = -1;
243 1.1 mrg
244 1.1 mrg if (u != NULL)
245 1.1 mrg {
246 1.1 mrg result = sseek(u->s, *offset, *whence);
247 1.1 mrg
248 1.1 mrg unlock_unit (u);
249 1.1 mrg }
250 1.1 mrg
251 1.1 mrg if (status)
252 1.1 mrg *status = (result < 0 ? -1 : 0);
253 1.1 mrg }
254 1.1 mrg
255 1.1 mrg
256 1.1 mrg
257 1.1 mrg /* FTELL intrinsic */
258 1.1 mrg
259 1.1 mrg static gfc_offset
260 1.1 mrg gf_ftell (int unit)
261 1.1 mrg {
262 1.1 mrg gfc_unit *u = find_unit (unit);
263 1.1 mrg if (u == NULL)
264 1.1 mrg return -1;
265 1.1 mrg int pos = fbuf_reset (u);
266 1.1 mrg if (pos != 0)
267 1.1 mrg sseek (u->s, pos, SEEK_CUR);
268 1.1 mrg gfc_offset ret = stell (u->s);
269 1.1 mrg unlock_unit (u);
270 1.1 mrg return ret;
271 1.1 mrg }
272 1.1 mrg
273 1.1 mrg
274 1.1 mrg extern GFC_IO_INT PREFIX(ftell) (int *);
275 1.1 mrg export_proto_np(PREFIX(ftell));
276 1.1 mrg
277 1.1 mrg GFC_IO_INT
278 1.1 mrg PREFIX(ftell) (int *unit)
279 1.1 mrg {
280 1.1 mrg return gf_ftell (*unit);
281 1.1 mrg }
282 1.1 mrg
283 1.1 mrg
284 1.1 mrg #define FTELL_SUB(kind) \
285 1.1 mrg extern void ftell_i ## kind ## _sub (int *, GFC_INTEGER_ ## kind *); \
286 1.1 mrg export_proto(ftell_i ## kind ## _sub); \
287 1.1 mrg void \
288 1.1 mrg ftell_i ## kind ## _sub (int *unit, GFC_INTEGER_ ## kind *offset) \
289 1.1 mrg { \
290 1.1 mrg *offset = gf_ftell (*unit); \
291 1.1 mrg }
292 1.1 mrg
293 1.1 mrg FTELL_SUB(1)
294 1.1 mrg FTELL_SUB(2)
295 1.1 mrg FTELL_SUB(4)
296 1.1 mrg FTELL_SUB(8)
297 1.1 mrg
298 1.1 mrg
299 1.1 mrg
300 1.1 mrg /* LOGICAL FUNCTION ISATTY(UNIT)
301 1.1 mrg INTEGER, INTENT(IN) :: UNIT */
302 1.1 mrg
303 1.1 mrg extern GFC_LOGICAL_4 isatty_l4 (int *);
304 1.1 mrg export_proto(isatty_l4);
305 1.1 mrg
306 1.1 mrg GFC_LOGICAL_4
307 1.1 mrg isatty_l4 (int *unit)
308 1.1 mrg {
309 1.1 mrg gfc_unit *u;
310 1.1 mrg GFC_LOGICAL_4 ret = 0;
311 1.1 mrg
312 1.1 mrg u = find_unit (*unit);
313 1.1 mrg if (u != NULL)
314 1.1 mrg {
315 1.1 mrg ret = (GFC_LOGICAL_4) stream_isatty (u->s);
316 1.1 mrg unlock_unit (u);
317 1.1 mrg }
318 1.1 mrg return ret;
319 1.1 mrg }
320 1.1 mrg
321 1.1 mrg
322 1.1 mrg extern GFC_LOGICAL_8 isatty_l8 (int *);
323 1.1 mrg export_proto(isatty_l8);
324 1.1 mrg
325 1.1 mrg GFC_LOGICAL_8
326 1.1 mrg isatty_l8 (int *unit)
327 1.1 mrg {
328 1.1 mrg gfc_unit *u;
329 1.1 mrg GFC_LOGICAL_8 ret = 0;
330 1.1 mrg
331 1.1 mrg u = find_unit (*unit);
332 1.1 mrg if (u != NULL)
333 1.1 mrg {
334 1.1 mrg ret = (GFC_LOGICAL_8) stream_isatty (u->s);
335 1.1 mrg unlock_unit (u);
336 1.1 mrg }
337 1.1 mrg return ret;
338 1.1 mrg }
339 1.1 mrg
340 1.1 mrg
341 1.1 mrg /* SUBROUTINE TTYNAM(UNIT,NAME)
342 1.1 mrg INTEGER,SCALAR,INTENT(IN) :: UNIT
343 1.1 mrg CHARACTER,SCALAR,INTENT(OUT) :: NAME */
344 1.1 mrg
345 1.1 mrg extern void ttynam_sub (int *, char *, gfc_charlen_type);
346 1.1 mrg export_proto(ttynam_sub);
347 1.1 mrg
348 1.1 mrg void
349 1.1 mrg ttynam_sub (int *unit, char *name, gfc_charlen_type name_len)
350 1.1 mrg {
351 1.1 mrg gfc_unit *u;
352 1.1 mrg int nlen;
353 1.1 mrg int err = 1;
354 1.1 mrg
355 1.1 mrg u = find_unit (*unit);
356 1.1 mrg if (u != NULL)
357 1.1 mrg {
358 1.1 mrg err = stream_ttyname (u->s, name, name_len);
359 1.1 mrg if (err == 0)
360 1.1 mrg {
361 1.1 mrg nlen = strlen (name);
362 1.1 mrg memset (&name[nlen], ' ', name_len - nlen);
363 1.1 mrg }
364 1.1 mrg
365 1.1 mrg unlock_unit (u);
366 1.1 mrg }
367 1.1 mrg if (err != 0)
368 1.1 mrg memset (name, ' ', name_len);
369 1.1 mrg }
370 1.1 mrg
371 1.1 mrg
372 1.1 mrg extern void ttynam (char **, gfc_charlen_type *, int);
373 1.1 mrg export_proto(ttynam);
374 1.1 mrg
375 1.1 mrg void
376 1.1 mrg ttynam (char **name, gfc_charlen_type *name_len, int unit)
377 1.1 mrg {
378 1.1 mrg gfc_unit *u;
379 1.1 mrg
380 1.1 mrg u = find_unit (unit);
381 1.1 mrg if (u != NULL)
382 1.1 mrg {
383 1.1 mrg *name = xmalloc (TTY_NAME_MAX);
384 1.1 mrg int err = stream_ttyname (u->s, *name, TTY_NAME_MAX);
385 1.1 mrg if (err == 0)
386 1.1 mrg {
387 1.1 mrg *name_len = strlen (*name);
388 1.1 mrg unlock_unit (u);
389 1.1 mrg return;
390 1.1 mrg }
391 1.1 mrg free (*name);
392 1.1 mrg unlock_unit (u);
393 1.1 mrg }
394 1.1 mrg
395 1.1 mrg *name_len = 0;
396 1.1 mrg *name = NULL;
397 1.1 mrg }
398