]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgfortran/io/io.h
PR fortran/25829 28655
[thirdparty/gcc.git] / libgfortran / io / io.h
CommitLineData
10256cbe 1/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
9a7b6ea7 2 Free Software Foundation, Inc.
6de9cd9a 3 Contributed by Andy Vaught
10256cbe 4 F2003 I/O support contributed by Jerry DeLisle
6de9cd9a
DN
5
6This file is part of the GNU Fortran 95 runtime library (libgfortran).
7
8Libgfortran is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13Libgfortran is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with Libgfortran; see the file COPYING. If not, write to
fe2ae685
KC
20the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21Boston, MA 02110-1301, USA. */
6de9cd9a 22
57dea9f6
TM
23/* As a special exception, if you link this library with other files,
24 some of which are compiled with GCC, to produce an executable,
25 this library does not by itself cause the resulting executable
26 to be covered by the GNU General Public License.
27 This exception does not however invalidate any other reasons why
28 the executable file might be covered by the GNU General Public License. */
29
6de9cd9a
DN
30#ifndef GFOR_IO_H
31#define GFOR_IO_H
32
33/* IO library include. */
34
6de9cd9a 35#include "libgfortran.h"
73e5b024 36
a0124624 37#include <setjmp.h>
5e805e44 38#include <gthr.h>
7d7b8bfe 39
6de9cd9a
DN
40/* Basic types used in data transfers. */
41
42typedef enum
43{ BT_NULL, BT_INTEGER, BT_LOGICAL, BT_CHARACTER, BT_REAL,
44 BT_COMPLEX
45}
46bt;
47
5e805e44
JJ
48struct st_parameter_dt;
49
6de9cd9a
DN
50typedef struct stream
51{
81f4be3c
TS
52 char *(*alloc_w_at) (struct stream *, int *, gfc_offset);
53 char *(*alloc_r_at) (struct stream *, int *, gfc_offset);
7d7b8bfe
RH
54 try (*sfree) (struct stream *);
55 try (*close) (struct stream *);
56 try (*seek) (struct stream *, gfc_offset);
200809cb 57 try (*trunc) (struct stream *);
0dc43461
JB
58 int (*read) (struct stream *, void *, size_t *);
59 int (*write) (struct stream *, const void *, size_t *);
82b8244c 60 try (*set) (struct stream *, int, size_t);
6de9cd9a
DN
61}
62stream;
63
10256cbe
JD
64typedef enum
65{ SYNC_BUFFERED, SYNC_UNBUFFERED, ASYNC }
66io_mode;
6de9cd9a
DN
67
68/* Macros for doing file I/O given a stream. */
69
70#define sfree(s) ((s)->sfree)(s)
71#define sclose(s) ((s)->close)(s)
72
73#define salloc_r(s, len) ((s)->alloc_r_at)(s, len, -1)
74#define salloc_w(s, len) ((s)->alloc_w_at)(s, len, -1)
75
76#define salloc_r_at(s, len, where) ((s)->alloc_r_at)(s, len, where)
77#define salloc_w_at(s, len, where) ((s)->alloc_w_at)(s, len, where)
78
79#define sseek(s, pos) ((s)->seek)(s, pos)
200809cb 80#define struncate(s) ((s)->trunc)(s)
0dc43461
JB
81#define sread(s, buf, nbytes) ((s)->read)(s, buf, nbytes)
82#define swrite(s, buf, nbytes) ((s)->write)(s, buf, nbytes)
6de9cd9a 83
82b8244c
JB
84#define sset(s, c, n) ((s)->set)(s, c, n)
85
d10fb73e
JD
86/* Macros for testing what kinds of I/O we are doing. */
87
88#define is_array_io(dtp) ((dtp)->internal_unit_desc)
89
90#define is_internal_unit(dtp) ((dtp)->u.p.unit_is_internal)
91
92#define is_stream_io(dtp) ((dtp)->u.p.current_unit->flags.access == ACCESS_STREAM)
93
965eec16 94/* The array_loop_spec contains the variables for the loops over index ranges
29dc5138
PT
95 that are encountered. Since the variables can be negative, ssize_t
96 is used. */
97
965eec16 98typedef struct array_loop_spec
29dc5138 99{
29dc5138
PT
100 /* Index counter for this dimension. */
101 ssize_t idx;
6de9cd9a 102
29dc5138
PT
103 /* Start for the index counter. */
104 ssize_t start;
105
106 /* End for the index counter. */
107 ssize_t end;
108
109 /* Step for the index counter. */
110 ssize_t step;
111}
965eec16
JD
112array_loop_spec;
113
114/* Representation of a namelist object in libgfortran
29dc5138 115
965eec16
JD
116 Namelist Records
117 &GROUPNAME OBJECT=value[s] [,OBJECT=value[s]].../
118 or
119 &GROUPNAME OBJECT=value[s] [,OBJECT=value[s]]...&END
120
8b6dba81 121 The object can be a fully qualified, compound name for an intrinsic
965eec16
JD
122 type, derived types or derived type components. So, a substring
123 a(:)%b(4)%ch(2:4)(1:7) has to be treated correctly in namelist
124 read. Hence full information about the structure of the object has
125 to be available to list_read.c and write.
126
127 These requirements are met by the following data structures.
128
129 namelist_info type contains all the scalar information about the
130 object and arrays of descriptor_dimension and array_loop_spec types for
29dc5138 131 arrays. */
6de9cd9a
DN
132
133typedef struct namelist_type
134{
29dc5138
PT
135
136 /* Object type, stored as GFC_DTYPE_xxxx. */
137 bt type;
138
139 /* Object name. */
6de9cd9a 140 char * var_name;
29dc5138
PT
141
142 /* Address for the start of the object's data. */
6de9cd9a 143 void * mem_pos;
29dc5138
PT
144
145 /* Flag to show that a read is to be attempted for this node. */
146 int touched;
147
148 /* Length of intrinsic type in bytes. */
6de9cd9a 149 int len;
29dc5138
PT
150
151 /* Rank of the object. */
152 int var_rank;
153
154 /* Overall size of the object in bytes. */
155 index_type size;
156
157 /* Length of character string. */
158 index_type string_length;
159
160 descriptor_dimension * dim;
965eec16 161 array_loop_spec * ls;
6de9cd9a
DN
162 struct namelist_type * next;
163}
164namelist_info;
165
166/* Options for the OPEN statement. */
167
168typedef enum
91b30ee5 169{ ACCESS_SEQUENTIAL, ACCESS_DIRECT, ACCESS_APPEND, ACCESS_STREAM,
6de9cd9a
DN
170 ACCESS_UNSPECIFIED
171}
172unit_access;
173
174typedef enum
175{ ACTION_READ, ACTION_WRITE, ACTION_READWRITE,
176 ACTION_UNSPECIFIED
177}
178unit_action;
179
180typedef enum
181{ BLANK_NULL, BLANK_ZERO, BLANK_UNSPECIFIED }
182unit_blank;
183
184typedef enum
185{ DELIM_NONE, DELIM_APOSTROPHE, DELIM_QUOTE,
186 DELIM_UNSPECIFIED
187}
188unit_delim;
189
190typedef enum
191{ FORM_FORMATTED, FORM_UNFORMATTED, FORM_UNSPECIFIED }
192unit_form;
193
194typedef enum
195{ POSITION_ASIS, POSITION_REWIND, POSITION_APPEND,
196 POSITION_UNSPECIFIED
197}
198unit_position;
199
200typedef enum
201{ STATUS_UNKNOWN, STATUS_OLD, STATUS_NEW, STATUS_SCRATCH,
202 STATUS_REPLACE, STATUS_UNSPECIFIED
203}
204unit_status;
205
206typedef enum
207{ PAD_YES, PAD_NO, PAD_UNSPECIFIED }
208unit_pad;
209
10256cbe
JD
210typedef enum
211{ DECIMAL_POINT, DECIMAL_COMMA, DECIMAL_UNSPECIFIED }
212unit_decimal;
213
214typedef enum
215{ ENCODING_UTF8, ENCODING_DEFAULT, ENCODING_UNSPECIFIED }
216unit_encoding;
217
218typedef enum
219{ ROUND_UP, ROUND_DOWN, ROUND_ZERO, ROUND_NEAREST, ROUND_COMPATIBLE,
220 ROUND_PROCDEFINED, ROUND_UNSPECIFIED }
221unit_round;
222
223/* NOTE: unit_sign must correspond with the sign_status enumerator in
224 st_parameter_dt to not break the ABI. */
225typedef enum
226{ SIGN_PROCDEFINED, SIGN_SUPPRESS, SIGN_PLUS, SIGN_UNSPECIFIED }
227unit_sign;
228
6de9cd9a
DN
229typedef enum
230{ ADVANCE_YES, ADVANCE_NO, ADVANCE_UNSPECIFIED }
231unit_advance;
232
55948b69
BD
233typedef enum
234{READING, WRITING}
235unit_mode;
6de9cd9a 236
10256cbe 237typedef enum
931149a6 238{ ASYNC_YES, ASYNC_NO, ASYNC_UNSPECIFIED }
10256cbe
JD
239unit_async;
240
5e805e44
JJ
241#define CHARACTER1(name) \
242 char * name; \
243 gfc_charlen_type name ## _len
244#define CHARACTER2(name) \
245 gfc_charlen_type name ## _len; \
246 char * name
247
6de9cd9a
DN
248typedef struct
249{
5e805e44
JJ
250 st_parameter_common common;
251 GFC_INTEGER_4 recl_in;
252 CHARACTER2 (file);
253 CHARACTER1 (status);
254 CHARACTER2 (access);
255 CHARACTER1 (form);
256 CHARACTER2 (blank);
257 CHARACTER1 (position);
258 CHARACTER2 (action);
259 CHARACTER1 (delim);
260 CHARACTER2 (pad);
181c9f4a 261 CHARACTER1 (convert);
10256cbe
JD
262 CHARACTER2 (decimal);
263 CHARACTER1 (encoding);
264 CHARACTER2 (round);
265 CHARACTER1 (sign);
266 CHARACTER2 (asynchronous);
5e805e44
JJ
267}
268st_parameter_open;
6de9cd9a 269
5e805e44 270#define IOPARM_CLOSE_HAS_STATUS (1 << 7)
6de9cd9a 271
5e805e44
JJ
272typedef struct
273{
274 st_parameter_common common;
275 CHARACTER1 (status);
276}
277st_parameter_close;
6de9cd9a 278
5e805e44
JJ
279typedef struct
280{
281 st_parameter_common common;
282}
283st_parameter_filepos;
284
285#define IOPARM_INQUIRE_HAS_EXIST (1 << 7)
286#define IOPARM_INQUIRE_HAS_OPENED (1 << 8)
287#define IOPARM_INQUIRE_HAS_NUMBER (1 << 9)
288#define IOPARM_INQUIRE_HAS_NAMED (1 << 10)
289#define IOPARM_INQUIRE_HAS_NEXTREC (1 << 11)
290#define IOPARM_INQUIRE_HAS_RECL_OUT (1 << 12)
91b30ee5
JD
291#define IOPARM_INQUIRE_HAS_STRM_POS_OUT (1 << 13)
292#define IOPARM_INQUIRE_HAS_FILE (1 << 14)
293#define IOPARM_INQUIRE_HAS_ACCESS (1 << 15)
294#define IOPARM_INQUIRE_HAS_FORM (1 << 16)
295#define IOPARM_INQUIRE_HAS_BLANK (1 << 17)
296#define IOPARM_INQUIRE_HAS_POSITION (1 << 18)
297#define IOPARM_INQUIRE_HAS_ACTION (1 << 19)
298#define IOPARM_INQUIRE_HAS_DELIM (1 << 20)
299#define IOPARM_INQUIRE_HAS_PAD (1 << 21)
300#define IOPARM_INQUIRE_HAS_NAME (1 << 22)
301#define IOPARM_INQUIRE_HAS_SEQUENTIAL (1 << 23)
302#define IOPARM_INQUIRE_HAS_DIRECT (1 << 24)
303#define IOPARM_INQUIRE_HAS_FORMATTED (1 << 25)
304#define IOPARM_INQUIRE_HAS_UNFORMATTED (1 << 26)
305#define IOPARM_INQUIRE_HAS_READ (1 << 27)
306#define IOPARM_INQUIRE_HAS_WRITE (1 << 28)
307#define IOPARM_INQUIRE_HAS_READWRITE (1 << 29)
308#define IOPARM_INQUIRE_HAS_CONVERT (1 << 30)
10256cbe
JD
309#define IOPARM_INQUIRE_HAS_FLAGS2 (1 << 31)
310
311#define IOPARM_INQUIRE_HAS_ASYNCHRONOUS (1 << 0)
312#define IOPARM_INQUIRE_HAS_DECIMAL (1 << 1)
313#define IOPARM_INQUIRE_HAS_ENCODING (1 << 2)
314#define IOPARM_INQUIRE_HAS_PENDING (1 << 3)
315#define IOPARM_INQUIRE_HAS_ROUND (1 << 4)
316#define IOPARM_INQUIRE_HAS_SIGN (1 << 5)
317#define IOPARM_INQUIRE_HAS_SIZE (1 << 6)
318#define IOPARM_INQUIRE_HAS_ID (1 << 7)
b8d5e926 319
5e805e44
JJ
320typedef struct
321{
322 st_parameter_common common;
323 GFC_INTEGER_4 *exist, *opened, *number, *named;
324 GFC_INTEGER_4 *nextrec, *recl_out;
91b30ee5 325 GFC_IO_INT *strm_pos_out;
5e805e44
JJ
326 CHARACTER1 (file);
327 CHARACTER2 (access);
328 CHARACTER1 (form);
329 CHARACTER2 (blank);
330 CHARACTER1 (position);
331 CHARACTER2 (action);
332 CHARACTER1 (delim);
333 CHARACTER2 (pad);
334 CHARACTER1 (name);
335 CHARACTER2 (sequential);
336 CHARACTER1 (direct);
337 CHARACTER2 (formatted);
338 CHARACTER1 (unformatted);
339 CHARACTER2 (read);
340 CHARACTER1 (write);
341 CHARACTER2 (readwrite);
181c9f4a 342 CHARACTER1 (convert);
10256cbe
JD
343 GFC_INTEGER_4 flags2;
344 CHARACTER1 (asynchronous);
931149a6 345 CHARACTER2 (decimal);
10256cbe 346 CHARACTER1 (encoding);
931149a6 347 CHARACTER2 (pending);
10256cbe 348 CHARACTER1 (round);
931149a6 349 CHARACTER2 (sign);
10256cbe 350 GFC_INTEGER_4 *size;
931149a6 351 GFC_INTEGER_4 *id;
5e805e44
JJ
352}
353st_parameter_inquire;
354
355struct gfc_unit;
356struct format_data;
357
358#define IOPARM_DT_LIST_FORMAT (1 << 7)
359#define IOPARM_DT_NAMELIST_READ_MODE (1 << 8)
360#define IOPARM_DT_HAS_REC (1 << 9)
361#define IOPARM_DT_HAS_SIZE (1 << 10)
362#define IOPARM_DT_HAS_IOLENGTH (1 << 11)
363#define IOPARM_DT_HAS_FORMAT (1 << 12)
364#define IOPARM_DT_HAS_ADVANCE (1 << 13)
365#define IOPARM_DT_HAS_INTERNAL_UNIT (1 << 14)
366#define IOPARM_DT_HAS_NAMELIST_NAME (1 << 15)
10256cbe
JD
367#define IOPARM_DT_HAS_ID (1 << 16)
368#define IOPARM_DT_HAS_POS (1 << 17)
369#define IOPARM_DT_HAS_ASYNCHRONOUS (1 << 18)
370#define IOPARM_DT_HAS_BLANK (1 << 19)
371#define IOPARM_DT_HAS_DECIMAL (1 << 20)
372#define IOPARM_DT_HAS_DELIM (1 << 21)
373#define IOPARM_DT_HAS_PAD (1 << 22)
374#define IOPARM_DT_HAS_ROUND (1 << 23)
375#define IOPARM_DT_HAS_SIGN (1 << 24)
5e805e44
JJ
376/* Internal use bit. */
377#define IOPARM_DT_IONML_SET (1 << 31)
378
379typedef struct st_parameter_dt
380{
381 st_parameter_common common;
91b30ee5 382 GFC_IO_INT rec;
cf794652 383 GFC_IO_INT *size, *iolength;
59154ed2 384 gfc_array_char *internal_unit_desc;
5e805e44
JJ
385 CHARACTER1 (format);
386 CHARACTER2 (advance);
387 CHARACTER1 (internal_unit);
388 CHARACTER2 (namelist_name);
10256cbe
JD
389 GFC_IO_INT *id;
390 GFC_IO_INT pos;
391 CHARACTER1 (asynchronous);
392 CHARACTER2 (blank);
393 CHARACTER1 (decimal);
394 CHARACTER2 (delim);
395 CHARACTER1 (pad);
396 CHARACTER2 (round);
397 CHARACTER1 (sign);
5e805e44
JJ
398 /* Private part of the structure. The compiler just needs
399 to reserve enough space. */
400 union
401 {
402 struct
403 {
404 void (*transfer) (struct st_parameter_dt *, bt, void *, int,
405 size_t, size_t);
406 struct gfc_unit *current_unit;
c9f15d9c
JD
407 /* Item number in a formatted data transfer. Also used in namelist
408 read_logical as an index into line_buffer. */
409 int item_count;
5e805e44
JJ
410 unit_mode mode;
411 unit_blank blank_status;
931149a6 412 unit_pad pad_status;
10256cbe 413 enum { SIGN_S, SIGN_SS, SIGN_SP } sign_status;
5e805e44
JJ
414 int scale_factor;
415 int max_pos; /* Maximum righthand column written to. */
416 /* Number of skips + spaces to be done for T and X-editing. */
417 int skips;
418 /* Number of spaces to be done for T and X-editing. */
419 int pending_spaces;
8824fd4c
FXC
420 /* Whether an EOR condition was encountered. Value is:
421 0 if no EOR was encountered
422 1 if an EOR was encountered due to a 1-byte marker (LF)
423 2 if an EOR was encountered due to a 2-bytes marker (CRLF) */
424 int sf_seen_eor;
5e805e44 425 unit_advance advance_status;
10256cbe 426 unit_decimal decimal_status;
931149a6 427 unit_delim delim_status;
b90ba157
RH
428
429 unsigned reversion_flag : 1; /* Format reversion has occurred. */
430 unsigned first_item : 1;
431 unsigned seen_dollar : 1;
b90ba157
RH
432 unsigned eor_condition : 1;
433 unsigned no_leading_blank : 1;
434 unsigned char_flag : 1;
435 unsigned input_complete : 1;
436 unsigned at_eol : 1;
437 unsigned comma_flag : 1;
5e805e44
JJ
438 /* A namelist specific flag used in the list directed library
439 to flag that calls are being made from namelist read (eg. to
440 ignore comments or to treat '/' as a terminator) */
b90ba157 441 unsigned namelist_mode : 1;
5e805e44
JJ
442 /* A namelist specific flag used in the list directed library
443 to flag read errors and return, so that an attempt can be
444 made to read a new object name. */
b90ba157 445 unsigned nml_read_error : 1;
b14c7e14
JD
446 /* A sequential formatted read specific flag used to signal that a
447 character string is being read so don't use commas to shorten a
448 formatted field width. */
449 unsigned sf_read_comma : 1;
c9f15d9c 450 /* A namelist specific flag used to enable reading input from
d57d3424 451 line_buffer for logical reads. */
c9f15d9c 452 unsigned line_buffer_enabled : 1;
6f34d6e0
JD
453 /* An internal unit specific flag used to identify that the associated
454 unit is internal. */
455 unsigned unit_is_internal : 1;
807fb853
JD
456 /* An internal unit specific flag to signify an EOF condition for list
457 directed read. */
458 unsigned at_eof : 1;
459 /* 16 unused bits. */
b90ba157
RH
460
461 char last_char;
462 char nml_delim;
463
5e805e44
JJ
464 int repeat_count;
465 int saved_length;
466 int saved_used;
467 bt saved_type;
468 char *saved_string;
469 char *scratch;
470 char *line_buffer;
471 struct format_data *fmt;
472 jmp_buf *eof_jump;
473 namelist_info *ionml;
25292a1b
JD
474 /* A flag used to identify when a non-standard expanded namelist read
475 has occurred. */
476 int expanded_read;
b90ba157
RH
477 /* Storage area for values except for strings. Must be large
478 enough to hold a complex value (two reals) of the largest
479 kind. */
480 char value[32];
d57d3424 481 gfc_offset size_used;
5e805e44 482 } p;
ebf85e50
JJ
483 /* This pad size must be equal to the pad_size declared in
484 trans-io.c (gfc_build_io_library_fndecls). The above structure
485 must be smaller or equal to this array. */
486 char pad[16 * sizeof (char *) + 32 * sizeof (int)];
5e805e44 487 } u;
6de9cd9a 488}
5e805e44 489st_parameter_dt;
6de9cd9a 490
ebf85e50
JJ
491/* Ensure st_parameter_dt's u.pad is bigger or equal to u.p. */
492extern char check_st_parameter_dt[sizeof (((st_parameter_dt *) 0)->u.pad)
493 >= sizeof (((st_parameter_dt *) 0)->u.p)
494 ? 1 : -1];
495
10256cbe
JD
496#define IOPARM_WAIT_HAS_ID (1 << 7)
497
498typedef struct
499{
500 st_parameter_common common;
501 CHARACTER1 (id);
502}
503st_parameter_wait;
504
505
5e805e44
JJ
506#undef CHARACTER1
507#undef CHARACTER2
6de9cd9a
DN
508
509typedef struct
510{
511 unit_access access;
512 unit_action action;
513 unit_blank blank;
514 unit_delim delim;
515 unit_form form;
516 int is_notpadded;
517 unit_position position;
518 unit_status status;
519 unit_pad pad;
10256cbe
JD
520 unit_decimal decimal;
521 unit_encoding encoding;
522 unit_round round;
523 unit_sign sign;
181c9f4a 524 unit_convert convert;
b0c6db58 525 int has_recl;
10256cbe 526 unit_async async;
6de9cd9a
DN
527}
528unit_flags;
529
530
909087e0 531typedef struct gfc_unit
6de9cd9a
DN
532{
533 int unit_number;
6de9cd9a 534 stream *s;
965eec16
JD
535
536 /* Treap links. */
537 struct gfc_unit *left, *right;
6de9cd9a
DN
538 int priority;
539
108bc190
TK
540 int read_bad, current_record, saved_pos, previous_nonadvancing_write;
541
6de9cd9a
DN
542 enum
543 { NO_ENDFILE, AT_ENDFILE, AFTER_ENDFILE }
544 endfile;
545
5e805e44 546 unit_mode mode;
6de9cd9a 547 unit_flags flags;
5e805e44 548
07b3bbf2
TK
549 /* recl -- Record length of the file.
550 last_record -- Last record number read or written
551 maxrec -- Maximum record number in a direct access file
552 bytes_left -- Bytes left in current record.
553 strm_pos -- Current position in file for STREAM I/O.
554 recl_subrecord -- Maximum length for subrecord.
555 bytes_left_subrecord -- Bytes left in current subrecord. */
556 gfc_offset recl, last_record, maxrec, bytes_left, strm_pos,
557 recl_subrecord, bytes_left_subrecord;
558
559 /* Set to 1 if we have read a subrecord. */
560
561 int continued;
6de9cd9a 562
5e805e44
JJ
563 __gthread_mutex_t lock;
564 /* Number of threads waiting to acquire this unit's lock.
565 When non-zero, close_unit doesn't only removes the unit
566 from the UNIT_ROOT tree, but doesn't free it and the
567 last of the waiting threads will do that.
568 This must be either atomically increased/decreased, or
569 always guarded by UNIT_LOCK. */
570 int waiting;
571 /* Flag set by close_unit if the unit as been closed.
572 Must be manipulated under unit's lock. */
573 int closed;
574
965eec16
JD
575 /* For traversing arrays */
576 array_loop_spec *ls;
577 int rank;
5e805e44 578
6de9cd9a 579 int file_len;
5e805e44 580 char *file;
6de9cd9a 581}
909087e0 582gfc_unit;
6de9cd9a 583
6de9cd9a
DN
584/* Format tokens. Only about half of these can be stored in the
585 format nodes. */
586
587typedef enum
588{
589 FMT_NONE = 0, FMT_UNKNOWN, FMT_SIGNED_INT, FMT_ZERO, FMT_POSINT, FMT_PERIOD,
590 FMT_COMMA, FMT_COLON, FMT_SLASH, FMT_DOLLAR, FMT_T, FMT_TR, FMT_TL,
591 FMT_LPAREN, FMT_RPAREN, FMT_X, FMT_S, FMT_SS, FMT_SP, FMT_STRING,
592 FMT_BADSTRING, FMT_P, FMT_I, FMT_B, FMT_BN, FMT_BZ, FMT_O, FMT_Z, FMT_F,
10256cbe
JD
593 FMT_E, FMT_EN, FMT_ES, FMT_G, FMT_L, FMT_A, FMT_D, FMT_H, FMT_END, FMT_DC,
594 FMT_DP
6de9cd9a
DN
595}
596format_token;
597
598
599/* Format nodes. A format string is converted into a tree of these
600 structures, which is traversed as part of a data transfer statement. */
601
602typedef struct fnode
603{
604 format_token format;
605 int repeat;
606 struct fnode *next;
607 char *source;
608
609 union
610 {
611 struct
612 {
613 int w, d, e;
614 }
615 real;
616
617 struct
618 {
619 int length;
620 char *p;
621 }
622 string;
623
624 struct
625 {
626 int w, m;
627 }
628 integer;
629
630 int w;
631 int k;
632 int r;
633 int n;
634
635 struct fnode *child;
636 }
637 u;
638
639 /* Members for traversing the tree during data transfer. */
640
641 int count;
642 struct fnode *current;
643
644}
645fnode;
646
647
648/* unix.c */
649
7d7b8bfe
RH
650extern int move_pos_offset (stream *, int);
651internal_proto(move_pos_offset);
6de9cd9a 652
7d7b8bfe
RH
653extern int compare_files (stream *, stream *);
654internal_proto(compare_files);
6de9cd9a 655
5e805e44 656extern stream *open_external (st_parameter_open *, unit_flags *);
7d7b8bfe 657internal_proto(open_external);
6de9cd9a 658
9370b3c0 659extern stream *open_internal (char *, int, gfc_offset);
7d7b8bfe 660internal_proto(open_internal);
6de9cd9a 661
7d7b8bfe
RH
662extern stream *input_stream (void);
663internal_proto(input_stream);
6de9cd9a 664
7d7b8bfe
RH
665extern stream *output_stream (void);
666internal_proto(output_stream);
6de9cd9a 667
fbac3363
DE
668extern stream *error_stream (void);
669internal_proto(error_stream);
670
ad238e4f 671extern int compare_file_filename (gfc_unit *, const char *, int);
7d7b8bfe 672internal_proto(compare_file_filename);
6de9cd9a 673
5e805e44 674extern gfc_unit *find_file (const char *file, gfc_charlen_type file_len);
7d7b8bfe 675internal_proto(find_file);
6de9cd9a 676
7d7b8bfe
RH
677extern int stream_at_bof (stream *);
678internal_proto(stream_at_bof);
6de9cd9a 679
7d7b8bfe
RH
680extern int stream_at_eof (stream *);
681internal_proto(stream_at_eof);
6de9cd9a 682
7d7b8bfe
RH
683extern int delete_file (gfc_unit *);
684internal_proto(delete_file);
6de9cd9a 685
5e805e44 686extern int file_exists (const char *file, gfc_charlen_type file_len);
7d7b8bfe 687internal_proto(file_exists);
6de9cd9a 688
7d7b8bfe
RH
689extern const char *inquire_sequential (const char *, int);
690internal_proto(inquire_sequential);
6de9cd9a 691
7d7b8bfe
RH
692extern const char *inquire_direct (const char *, int);
693internal_proto(inquire_direct);
6de9cd9a 694
7d7b8bfe
RH
695extern const char *inquire_formatted (const char *, int);
696internal_proto(inquire_formatted);
6de9cd9a 697
7d7b8bfe
RH
698extern const char *inquire_unformatted (const char *, int);
699internal_proto(inquire_unformatted);
6de9cd9a 700
7d7b8bfe
RH
701extern const char *inquire_read (const char *, int);
702internal_proto(inquire_read);
6de9cd9a 703
7d7b8bfe
RH
704extern const char *inquire_write (const char *, int);
705internal_proto(inquire_write);
6de9cd9a 706
7d7b8bfe
RH
707extern const char *inquire_readwrite (const char *, int);
708internal_proto(inquire_readwrite);
6de9cd9a 709
7d7b8bfe
RH
710extern gfc_offset file_length (stream *);
711internal_proto(file_length);
6de9cd9a 712
7d7b8bfe
RH
713extern gfc_offset file_position (stream *);
714internal_proto(file_position);
6de9cd9a 715
7d7b8bfe
RH
716extern int is_seekable (stream *);
717internal_proto(is_seekable);
6de9cd9a 718
7ab8aa36
JD
719extern int is_special (stream *);
720internal_proto(is_special);
721
b65b81f9
FXC
722extern int is_preconnected (stream *);
723internal_proto(is_preconnected);
724
159840cb
FXC
725extern void flush_if_preconnected (stream *);
726internal_proto(flush_if_preconnected);
727
7d7b8bfe
RH
728extern void empty_internal_buffer(stream *);
729internal_proto(empty_internal_buffer);
6de9cd9a 730
7d7b8bfe
RH
731extern try flush (stream *);
732internal_proto(flush);
6de9cd9a 733
ae8b8789
FXC
734extern int stream_isatty (stream *);
735internal_proto(stream_isatty);
736
737extern char * stream_ttyname (stream *);
738internal_proto(stream_ttyname);
739
5d723e54
FXC
740extern gfc_offset stream_offset (stream *s);
741internal_proto(stream_offset);
742
10c682a0
FXC
743extern int unpack_filename (char *, const char *, int);
744internal_proto(unpack_filename);
745
6de9cd9a
DN
746/* unit.c */
747
5e805e44
JJ
748/* Maximum file offset, computed at library initialization time. */
749extern gfc_offset max_offset;
750internal_proto(max_offset);
751
752/* Unit tree root. */
753extern gfc_unit *unit_root;
754internal_proto(unit_root);
755
756extern __gthread_mutex_t unit_lock;
757internal_proto(unit_lock);
6de9cd9a 758
7d7b8bfe
RH
759extern int close_unit (gfc_unit *);
760internal_proto(close_unit);
6de9cd9a 761
54ffdb12
JD
762extern gfc_unit *get_internal_unit (st_parameter_dt *);
763internal_proto(get_internal_unit);
764
765extern void free_internal_unit (st_parameter_dt *);
766internal_proto(free_internal_unit);
91b30ee5 767
7d7b8bfe
RH
768extern gfc_unit *find_unit (int);
769internal_proto(find_unit);
6de9cd9a 770
5e805e44 771extern gfc_unit *find_or_create_unit (int);
59c0928b 772internal_proto(find_or_create_unit);
5e805e44
JJ
773
774extern gfc_unit *get_unit (st_parameter_dt *, int);
7d7b8bfe 775internal_proto(get_unit);
6de9cd9a 776
5e805e44
JJ
777extern void unlock_unit (gfc_unit *);
778internal_proto(unlock_unit);
779
16d962d9
JD
780extern void update_position (gfc_unit *);
781internal_proto(update_position);
782
108bc190
TK
783extern void finish_last_advance_record (gfc_unit *u);
784internal_proto (finish_last_advance_record);
785
6de9cd9a
DN
786/* open.c */
787
5e805e44 788extern gfc_unit *new_unit (st_parameter_open *, gfc_unit *, unit_flags *);
7d7b8bfe 789internal_proto(new_unit);
6de9cd9a
DN
790
791/* format.c */
792
5e805e44 793extern void parse_format (st_parameter_dt *);
7d7b8bfe 794internal_proto(parse_format);
6de9cd9a 795
5e805e44 796extern const fnode *next_format (st_parameter_dt *);
7d7b8bfe 797internal_proto(next_format);
6de9cd9a 798
5e805e44 799extern void unget_format (st_parameter_dt *, const fnode *);
7d7b8bfe 800internal_proto(unget_format);
6de9cd9a 801
5e805e44 802extern void format_error (st_parameter_dt *, const fnode *, const char *);
7d7b8bfe 803internal_proto(format_error);
6de9cd9a 804
5e805e44
JJ
805extern void free_format_data (st_parameter_dt *);
806internal_proto(free_format_data);
6de9cd9a
DN
807
808/* transfer.c */
809
810#define SCRATCH_SIZE 300
811
7d7b8bfe
RH
812extern const char *type_name (bt);
813internal_proto(type_name);
6de9cd9a 814
5e805e44 815extern void *read_block (st_parameter_dt *, int *);
7d7b8bfe 816internal_proto(read_block);
6de9cd9a 817
0853054e
JD
818extern char *read_sf (st_parameter_dt *, int *, int);
819internal_proto(read_sf);
820
5e805e44 821extern void *write_block (st_parameter_dt *, int);
7d7b8bfe 822internal_proto(write_block);
6de9cd9a 823
9370b3c0
TK
824extern gfc_offset next_array_record (st_parameter_dt *, array_loop_spec *,
825 int*);
965eec16
JD
826internal_proto(next_array_record);
827
9370b3c0
TK
828extern gfc_offset init_loop_spec (gfc_array_char *, array_loop_spec *,
829 gfc_offset *);
965eec16
JD
830internal_proto(init_loop_spec);
831
5e805e44 832extern void next_record (st_parameter_dt *, int);
7d7b8bfe 833internal_proto(next_record);
6de9cd9a 834
181c9f4a
TK
835extern void reverse_memcpy (void *, const void *, size_t);
836internal_proto (reverse_memcpy);
837
10256cbe
JD
838extern void st_wait (st_parameter_wait *);
839export_proto(st_wait);
840
6de9cd9a
DN
841/* read.c */
842
32aa3bff 843extern void set_integer (void *, GFC_INTEGER_LARGEST, int);
7d7b8bfe 844internal_proto(set_integer);
6de9cd9a 845
32aa3bff 846extern GFC_UINTEGER_LARGEST max_value (int, int);
7d7b8bfe 847internal_proto(max_value);
6de9cd9a 848
5e805e44 849extern int convert_real (st_parameter_dt *, void *, const char *, int);
7d7b8bfe 850internal_proto(convert_real);
6de9cd9a 851
5e805e44 852extern void read_a (st_parameter_dt *, const fnode *, char *, int);
7d7b8bfe 853internal_proto(read_a);
6de9cd9a 854
5e805e44 855extern void read_f (st_parameter_dt *, const fnode *, char *, int);
7d7b8bfe 856internal_proto(read_f);
6de9cd9a 857
5e805e44 858extern void read_l (st_parameter_dt *, const fnode *, char *, int);
7d7b8bfe 859internal_proto(read_l);
6de9cd9a 860
5e805e44 861extern void read_x (st_parameter_dt *, int);
7d7b8bfe 862internal_proto(read_x);
6de9cd9a 863
5e805e44 864extern void read_radix (st_parameter_dt *, const fnode *, char *, int, int);
7d7b8bfe 865internal_proto(read_radix);
6de9cd9a 866
5e805e44 867extern void read_decimal (st_parameter_dt *, const fnode *, char *, int);
7d7b8bfe 868internal_proto(read_decimal);
6de9cd9a
DN
869
870/* list_read.c */
871
5e805e44
JJ
872extern void list_formatted_read (st_parameter_dt *, bt, void *, int, size_t,
873 size_t);
7d7b8bfe 874internal_proto(list_formatted_read);
6de9cd9a 875
5e805e44 876extern void finish_list_read (st_parameter_dt *);
7d7b8bfe 877internal_proto(finish_list_read);
6de9cd9a 878
5e805e44 879extern void namelist_read (st_parameter_dt *);
7d7b8bfe 880internal_proto(namelist_read);
6de9cd9a 881
5e805e44 882extern void namelist_write (st_parameter_dt *);
7d7b8bfe 883internal_proto(namelist_write);
6de9cd9a
DN
884
885/* write.c */
886
5e805e44 887extern void write_a (st_parameter_dt *, const fnode *, const char *, int);
7d7b8bfe 888internal_proto(write_a);
6de9cd9a 889
5e805e44 890extern void write_b (st_parameter_dt *, const fnode *, const char *, int);
7d7b8bfe 891internal_proto(write_b);
6de9cd9a 892
5e805e44 893extern void write_d (st_parameter_dt *, const fnode *, const char *, int);
7d7b8bfe 894internal_proto(write_d);
6de9cd9a 895
5e805e44 896extern void write_e (st_parameter_dt *, const fnode *, const char *, int);
7d7b8bfe 897internal_proto(write_e);
6de9cd9a 898
5e805e44 899extern void write_en (st_parameter_dt *, const fnode *, const char *, int);
7d7b8bfe 900internal_proto(write_en);
6de9cd9a 901
5e805e44 902extern void write_es (st_parameter_dt *, const fnode *, const char *, int);
7d7b8bfe 903internal_proto(write_es);
6de9cd9a 904
5e805e44 905extern void write_f (st_parameter_dt *, const fnode *, const char *, int);
7d7b8bfe 906internal_proto(write_f);
6de9cd9a 907
5e805e44 908extern void write_i (st_parameter_dt *, const fnode *, const char *, int);
7d7b8bfe 909internal_proto(write_i);
6de9cd9a 910
5e805e44 911extern void write_l (st_parameter_dt *, const fnode *, char *, int);
7d7b8bfe 912internal_proto(write_l);
6de9cd9a 913
5e805e44 914extern void write_o (st_parameter_dt *, const fnode *, const char *, int);
7d7b8bfe 915internal_proto(write_o);
6de9cd9a 916
5e805e44 917extern void write_x (st_parameter_dt *, int, int);
7d7b8bfe 918internal_proto(write_x);
6de9cd9a 919
5e805e44 920extern void write_z (st_parameter_dt *, const fnode *, const char *, int);
7d7b8bfe 921internal_proto(write_z);
6de9cd9a 922
5e805e44
JJ
923extern void list_formatted_write (st_parameter_dt *, bt, void *, int, size_t,
924 size_t);
7d7b8bfe 925internal_proto(list_formatted_write);
6de9cd9a 926
e5ef4b3b
JB
927/* size_from_kind.c */
928extern size_t size_from_real_kind (int);
929internal_proto(size_from_real_kind);
930
931extern size_t size_from_complex_kind (int);
932internal_proto(size_from_complex_kind);
933
5e805e44
JJ
934/* lock.c */
935extern void free_ionml (st_parameter_dt *);
936internal_proto(free_ionml);
937
938static inline void
939inc_waiting_locked (gfc_unit *u)
940{
941#ifdef HAVE_SYNC_FETCH_AND_ADD
942 (void) __sync_fetch_and_add (&u->waiting, 1);
943#else
944 u->waiting++;
945#endif
946}
947
948static inline int
949predec_waiting_locked (gfc_unit *u)
950{
951#ifdef HAVE_SYNC_FETCH_AND_ADD
952 return __sync_add_and_fetch (&u->waiting, -1);
953#else
954 return --u->waiting;
955#endif
956}
957
958static inline void
959dec_waiting_unlocked (gfc_unit *u)
960{
961#ifdef HAVE_SYNC_FETCH_AND_ADD
962 (void) __sync_fetch_and_add (&u->waiting, -1);
963#else
964 __gthread_mutex_lock (&unit_lock);
965 u->waiting--;
966 __gthread_mutex_unlock (&unit_lock);
967#endif
968}
969
6de9cd9a 970#endif
eaa90d25 971