1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
2 Free Software Foundation, Inc.
3 Contributed by Andy Vaught
4 F2003 I/O support contributed by Jerry DeLisle
6 This file is part of the GNU Fortran 95 runtime library (libgfortran).
8 Libgfortran is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
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 You should have received a copy of the GNU General Public License
19 along with Libgfortran; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
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. */
33 /* IO library include. */
35 #include "libgfortran.h"
40 /* Basic types used in data transfers. */
43 { BT_NULL, BT_INTEGER, BT_LOGICAL, BT_CHARACTER, BT_REAL,
48 struct st_parameter_dt;
52 char *(*alloc_w_at) (struct stream *, int *, gfc_offset);
53 char *(*alloc_r_at) (struct stream *, int *, gfc_offset);
54 try (*sfree) (struct stream *);
55 try (*close) (struct stream *);
56 try (*seek) (struct stream *, gfc_offset);
57 try (*trunc) (struct stream *);
58 int (*read) (struct stream *, void *, size_t *);
59 int (*write) (struct stream *, const void *, size_t *);
60 try (*set) (struct stream *, int, size_t);
65 { SYNC_BUFFERED, SYNC_UNBUFFERED, ASYNC }
68 /* Macros for doing file I/O given a stream. */
70 #define sfree(s) ((s)->sfree)(s)
71 #define sclose(s) ((s)->close)(s)
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)
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)
79 #define sseek(s, pos) ((s)->seek)(s, pos)
80 #define struncate(s) ((s)->trunc)(s)
81 #define sread(s, buf, nbytes) ((s)->read)(s, buf, nbytes)
82 #define swrite(s, buf, nbytes) ((s)->write)(s, buf, nbytes)
84 #define sset(s, c, n) ((s)->set)(s, c, n)
86 /* Macros for testing what kinds of I/O we are doing. */
88 #define is_array_io(dtp) ((dtp)->internal_unit_desc)
90 #define is_internal_unit(dtp) ((dtp)->u.p.unit_is_internal)
92 #define is_stream_io(dtp) ((dtp)->u.p.current_unit->flags.access == ACCESS_STREAM)
94 /* The array_loop_spec contains the variables for the loops over index ranges
95 that are encountered. Since the variables can be negative, ssize_t
98 typedef struct array_loop_spec
100 /* Index counter for this dimension. */
103 /* Start for the index counter. */
106 /* End for the index counter. */
109 /* Step for the index counter. */
114 /* Representation of a namelist object in libgfortran
117 &GROUPNAME OBJECT=value[s] [,OBJECT=value[s]].../
119 &GROUPNAME OBJECT=value[s] [,OBJECT=value[s]]...&END
121 The object can be a fully qualified, compound name for an intrinsic
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.
127 These requirements are met by the following data structures.
129 namelist_info type contains all the scalar information about the
130 object and arrays of descriptor_dimension and array_loop_spec types for
133 typedef struct namelist_type
136 /* Object type, stored as GFC_DTYPE_xxxx. */
142 /* Address for the start of the object's data. */
145 /* Flag to show that a read is to be attempted for this node. */
148 /* Length of intrinsic type in bytes. */
151 /* Rank of the object. */
154 /* Overall size of the object in bytes. */
157 /* Length of character string. */
158 index_type string_length;
160 descriptor_dimension * dim;
161 array_loop_spec * ls;
162 struct namelist_type * next;
166 /* Options for the OPEN statement. */
169 { ACCESS_SEQUENTIAL, ACCESS_DIRECT, ACCESS_APPEND, ACCESS_STREAM,
175 { ACTION_READ, ACTION_WRITE, ACTION_READWRITE,
181 { BLANK_NULL, BLANK_ZERO, BLANK_UNSPECIFIED }
185 { DELIM_NONE, DELIM_APOSTROPHE, DELIM_QUOTE,
191 { FORM_FORMATTED, FORM_UNFORMATTED, FORM_UNSPECIFIED }
195 { POSITION_ASIS, POSITION_REWIND, POSITION_APPEND,
201 { STATUS_UNKNOWN, STATUS_OLD, STATUS_NEW, STATUS_SCRATCH,
202 STATUS_REPLACE, STATUS_UNSPECIFIED
207 { PAD_YES, PAD_NO, PAD_UNSPECIFIED }
211 { DECIMAL_POINT, DECIMAL_COMMA, DECIMAL_UNSPECIFIED }
215 { ENCODING_UTF8, ENCODING_DEFAULT, ENCODING_UNSPECIFIED }
219 { ROUND_UP, ROUND_DOWN, ROUND_ZERO, ROUND_NEAREST, ROUND_COMPATIBLE,
220 ROUND_PROCDEFINED, ROUND_UNSPECIFIED }
223 /* NOTE: unit_sign must correspond with the sign_status enumerator in
224 st_parameter_dt to not break the ABI. */
226 { SIGN_PROCDEFINED, SIGN_SUPPRESS, SIGN_PLUS, SIGN_UNSPECIFIED }
230 { ADVANCE_YES, ADVANCE_NO, ADVANCE_UNSPECIFIED }
238 { ASYNC_YES, ASYNC_NO, AYSYNC_UNSPECIFIED }
241 #define CHARACTER1(name) \
243 gfc_charlen_type name ## _len
244 #define CHARACTER2(name) \
245 gfc_charlen_type name ## _len; \
250 st_parameter_common common;
251 GFC_INTEGER_4 recl_in;
257 CHARACTER1 (position);
261 CHARACTER1 (convert);
262 CHARACTER2 (decimal);
263 CHARACTER1 (encoding);
266 CHARACTER2 (asynchronous);
270 #define IOPARM_CLOSE_HAS_STATUS (1 << 7)
274 st_parameter_common common;
281 st_parameter_common common;
283 st_parameter_filepos;
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)
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)
309 #define IOPARM_INQUIRE_HAS_FLAGS2 (1 << 31)
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)
322 st_parameter_common common;
323 GFC_INTEGER_4 *exist, *opened, *number, *named;
324 GFC_INTEGER_4 *nextrec, *recl_out;
325 GFC_IO_INT *strm_pos_out;
330 CHARACTER1 (position);
335 CHARACTER2 (sequential);
337 CHARACTER2 (formatted);
338 CHARACTER1 (unformatted);
341 CHARACTER2 (readwrite);
342 CHARACTER1 (convert);
343 GFC_INTEGER_4 flags2;
344 CHARACTER1 (asynchronous);
345 CHARACTER1 (decimal);
346 CHARACTER1 (encoding);
347 CHARACTER1 (pending);
353 st_parameter_inquire;
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)
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)
376 /* Internal use bit. */
377 #define IOPARM_DT_IONML_SET (1 << 31)
379 typedef struct st_parameter_dt
381 st_parameter_common common;
383 GFC_IO_INT *size, *iolength;
384 gfc_array_char *internal_unit_desc;
386 CHARACTER2 (advance);
387 CHARACTER1 (internal_unit);
388 CHARACTER2 (namelist_name);
391 CHARACTER1 (asynchronous);
393 CHARACTER1 (decimal);
398 /* Private part of the structure. The compiler just needs
399 to reserve enough space. */
404 void (*transfer) (struct st_parameter_dt *, bt, void *, int,
406 struct gfc_unit *current_unit;
407 /* Item number in a formatted data transfer. Also used in namelist
408 read_logical as an index into line_buffer. */
411 unit_blank blank_status;
412 enum { SIGN_S, SIGN_SS, SIGN_SP } sign_status;
414 int max_pos; /* Maximum righthand column written to. */
415 /* Number of skips + spaces to be done for T and X-editing. */
417 /* Number of spaces to be done for T and X-editing. */
419 /* Whether an EOR condition was encountered. Value is:
420 0 if no EOR was encountered
421 1 if an EOR was encountered due to a 1-byte marker (LF)
422 2 if an EOR was encountered due to a 2-bytes marker (CRLF) */
424 unit_advance advance_status;
425 unit_decimal decimal_status;
427 unsigned reversion_flag : 1; /* Format reversion has occurred. */
428 unsigned first_item : 1;
429 unsigned seen_dollar : 1;
430 unsigned eor_condition : 1;
431 unsigned no_leading_blank : 1;
432 unsigned char_flag : 1;
433 unsigned input_complete : 1;
435 unsigned comma_flag : 1;
436 /* A namelist specific flag used in the list directed library
437 to flag that calls are being made from namelist read (eg. to
438 ignore comments or to treat '/' as a terminator) */
439 unsigned namelist_mode : 1;
440 /* A namelist specific flag used in the list directed library
441 to flag read errors and return, so that an attempt can be
442 made to read a new object name. */
443 unsigned nml_read_error : 1;
444 /* A sequential formatted read specific flag used to signal that a
445 character string is being read so don't use commas to shorten a
446 formatted field width. */
447 unsigned sf_read_comma : 1;
448 /* A namelist specific flag used to enable reading input from
449 line_buffer for logical reads. */
450 unsigned line_buffer_enabled : 1;
451 /* An internal unit specific flag used to identify that the associated
453 unsigned unit_is_internal : 1;
454 /* An internal unit specific flag to signify an EOF condition for list
457 /* 16 unused bits. */
469 struct format_data *fmt;
471 namelist_info *ionml;
472 /* A flag used to identify when a non-standard expanded namelist read
475 /* Storage area for values except for strings. Must be large
476 enough to hold a complex value (two reals) of the largest
479 gfc_offset size_used;
481 /* This pad size must be equal to the pad_size declared in
482 trans-io.c (gfc_build_io_library_fndecls). The above structure
483 must be smaller or equal to this array. */
484 char pad[16 * sizeof (char *) + 32 * sizeof (int)];
489 /* Ensure st_parameter_dt's u.pad is bigger or equal to u.p. */
490 extern char check_st_parameter_dt[sizeof (((st_parameter_dt *) 0)->u.pad)
491 >= sizeof (((st_parameter_dt *) 0)->u.p)
494 #define IOPARM_WAIT_HAS_ID (1 << 7)
498 st_parameter_common common;
515 unit_position position;
518 unit_decimal decimal;
519 unit_encoding encoding;
522 unit_convert convert;
529 typedef struct gfc_unit
535 struct gfc_unit *left, *right;
538 int read_bad, current_record, saved_pos, previous_nonadvancing_write;
541 { NO_ENDFILE, AT_ENDFILE, AFTER_ENDFILE }
547 /* recl -- Record length of the file.
548 last_record -- Last record number read or written
549 maxrec -- Maximum record number in a direct access file
550 bytes_left -- Bytes left in current record.
551 strm_pos -- Current position in file for STREAM I/O.
552 recl_subrecord -- Maximum length for subrecord.
553 bytes_left_subrecord -- Bytes left in current subrecord. */
554 gfc_offset recl, last_record, maxrec, bytes_left, strm_pos,
555 recl_subrecord, bytes_left_subrecord;
557 /* Set to 1 if we have read a subrecord. */
561 __gthread_mutex_t lock;
562 /* Number of threads waiting to acquire this unit's lock.
563 When non-zero, close_unit doesn't only removes the unit
564 from the UNIT_ROOT tree, but doesn't free it and the
565 last of the waiting threads will do that.
566 This must be either atomically increased/decreased, or
567 always guarded by UNIT_LOCK. */
569 /* Flag set by close_unit if the unit as been closed.
570 Must be manipulated under unit's lock. */
573 /* For traversing arrays */
582 /* Format tokens. Only about half of these can be stored in the
587 FMT_NONE = 0, FMT_UNKNOWN, FMT_SIGNED_INT, FMT_ZERO, FMT_POSINT, FMT_PERIOD,
588 FMT_COMMA, FMT_COLON, FMT_SLASH, FMT_DOLLAR, FMT_T, FMT_TR, FMT_TL,
589 FMT_LPAREN, FMT_RPAREN, FMT_X, FMT_S, FMT_SS, FMT_SP, FMT_STRING,
590 FMT_BADSTRING, FMT_P, FMT_I, FMT_B, FMT_BN, FMT_BZ, FMT_O, FMT_Z, FMT_F,
591 FMT_E, FMT_EN, FMT_ES, FMT_G, FMT_L, FMT_A, FMT_D, FMT_H, FMT_END, FMT_DC,
597 /* Format nodes. A format string is converted into a tree of these
598 structures, which is traversed as part of a data transfer statement. */
637 /* Members for traversing the tree during data transfer. */
640 struct fnode *current;
648 extern int move_pos_offset (stream *, int);
649 internal_proto(move_pos_offset);
651 extern int compare_files (stream *, stream *);
652 internal_proto(compare_files);
654 extern stream *open_external (st_parameter_open *, unit_flags *);
655 internal_proto(open_external);
657 extern stream *open_internal (char *, int, gfc_offset);
658 internal_proto(open_internal);
660 extern stream *input_stream (void);
661 internal_proto(input_stream);
663 extern stream *output_stream (void);
664 internal_proto(output_stream);
666 extern stream *error_stream (void);
667 internal_proto(error_stream);
669 extern int compare_file_filename (gfc_unit *, const char *, int);
670 internal_proto(compare_file_filename);
672 extern gfc_unit *find_file (const char *file, gfc_charlen_type file_len);
673 internal_proto(find_file);
675 extern int stream_at_bof (stream *);
676 internal_proto(stream_at_bof);
678 extern int stream_at_eof (stream *);
679 internal_proto(stream_at_eof);
681 extern int delete_file (gfc_unit *);
682 internal_proto(delete_file);
684 extern int file_exists (const char *file, gfc_charlen_type file_len);
685 internal_proto(file_exists);
687 extern const char *inquire_sequential (const char *, int);
688 internal_proto(inquire_sequential);
690 extern const char *inquire_direct (const char *, int);
691 internal_proto(inquire_direct);
693 extern const char *inquire_formatted (const char *, int);
694 internal_proto(inquire_formatted);
696 extern const char *inquire_unformatted (const char *, int);
697 internal_proto(inquire_unformatted);
699 extern const char *inquire_read (const char *, int);
700 internal_proto(inquire_read);
702 extern const char *inquire_write (const char *, int);
703 internal_proto(inquire_write);
705 extern const char *inquire_readwrite (const char *, int);
706 internal_proto(inquire_readwrite);
708 extern gfc_offset file_length (stream *);
709 internal_proto(file_length);
711 extern gfc_offset file_position (stream *);
712 internal_proto(file_position);
714 extern int is_seekable (stream *);
715 internal_proto(is_seekable);
717 extern int is_special (stream *);
718 internal_proto(is_special);
720 extern int is_preconnected (stream *);
721 internal_proto(is_preconnected);
723 extern void flush_if_preconnected (stream *);
724 internal_proto(flush_if_preconnected);
726 extern void empty_internal_buffer(stream *);
727 internal_proto(empty_internal_buffer);
729 extern try flush (stream *);
730 internal_proto(flush);
732 extern int stream_isatty (stream *);
733 internal_proto(stream_isatty);
735 extern char * stream_ttyname (stream *);
736 internal_proto(stream_ttyname);
738 extern gfc_offset stream_offset (stream *s);
739 internal_proto(stream_offset);
741 extern int unpack_filename (char *, const char *, int);
742 internal_proto(unpack_filename);
746 /* Maximum file offset, computed at library initialization time. */
747 extern gfc_offset max_offset;
748 internal_proto(max_offset);
750 /* Unit tree root. */
751 extern gfc_unit *unit_root;
752 internal_proto(unit_root);
754 extern __gthread_mutex_t unit_lock;
755 internal_proto(unit_lock);
757 extern int close_unit (gfc_unit *);
758 internal_proto(close_unit);
760 extern gfc_unit *get_internal_unit (st_parameter_dt *);
761 internal_proto(get_internal_unit);
763 extern void free_internal_unit (st_parameter_dt *);
764 internal_proto(free_internal_unit);
766 extern gfc_unit *find_unit (int);
767 internal_proto(find_unit);
769 extern gfc_unit *find_or_create_unit (int);
770 internal_proto(find_or_create_unit);
772 extern gfc_unit *get_unit (st_parameter_dt *, int);
773 internal_proto(get_unit);
775 extern void unlock_unit (gfc_unit *);
776 internal_proto(unlock_unit);
778 extern void update_position (gfc_unit *);
779 internal_proto(update_position);
781 extern void finish_last_advance_record (gfc_unit *u);
782 internal_proto (finish_last_advance_record);
786 extern gfc_unit *new_unit (st_parameter_open *, gfc_unit *, unit_flags *);
787 internal_proto(new_unit);
791 extern void parse_format (st_parameter_dt *);
792 internal_proto(parse_format);
794 extern const fnode *next_format (st_parameter_dt *);
795 internal_proto(next_format);
797 extern void unget_format (st_parameter_dt *, const fnode *);
798 internal_proto(unget_format);
800 extern void format_error (st_parameter_dt *, const fnode *, const char *);
801 internal_proto(format_error);
803 extern void free_format_data (st_parameter_dt *);
804 internal_proto(free_format_data);
808 #define SCRATCH_SIZE 300
810 extern const char *type_name (bt);
811 internal_proto(type_name);
813 extern void *read_block (st_parameter_dt *, int *);
814 internal_proto(read_block);
816 extern char *read_sf (st_parameter_dt *, int *, int);
817 internal_proto(read_sf);
819 extern void *write_block (st_parameter_dt *, int);
820 internal_proto(write_block);
822 extern gfc_offset next_array_record (st_parameter_dt *, array_loop_spec *,
824 internal_proto(next_array_record);
826 extern gfc_offset init_loop_spec (gfc_array_char *, array_loop_spec *,
828 internal_proto(init_loop_spec);
830 extern void next_record (st_parameter_dt *, int);
831 internal_proto(next_record);
833 extern void reverse_memcpy (void *, const void *, size_t);
834 internal_proto (reverse_memcpy);
836 extern void st_wait (st_parameter_wait *);
837 export_proto(st_wait);
841 extern void set_integer (void *, GFC_INTEGER_LARGEST, int);
842 internal_proto(set_integer);
844 extern GFC_UINTEGER_LARGEST max_value (int, int);
845 internal_proto(max_value);
847 extern int convert_real (st_parameter_dt *, void *, const char *, int);
848 internal_proto(convert_real);
850 extern void read_a (st_parameter_dt *, const fnode *, char *, int);
851 internal_proto(read_a);
853 extern void read_f (st_parameter_dt *, const fnode *, char *, int);
854 internal_proto(read_f);
856 extern void read_l (st_parameter_dt *, const fnode *, char *, int);
857 internal_proto(read_l);
859 extern void read_x (st_parameter_dt *, int);
860 internal_proto(read_x);
862 extern void read_radix (st_parameter_dt *, const fnode *, char *, int, int);
863 internal_proto(read_radix);
865 extern void read_decimal (st_parameter_dt *, const fnode *, char *, int);
866 internal_proto(read_decimal);
870 extern void list_formatted_read (st_parameter_dt *, bt, void *, int, size_t,
872 internal_proto(list_formatted_read);
874 extern void finish_list_read (st_parameter_dt *);
875 internal_proto(finish_list_read);
877 extern void namelist_read (st_parameter_dt *);
878 internal_proto(namelist_read);
880 extern void namelist_write (st_parameter_dt *);
881 internal_proto(namelist_write);
885 extern void write_a (st_parameter_dt *, const fnode *, const char *, int);
886 internal_proto(write_a);
888 extern void write_b (st_parameter_dt *, const fnode *, const char *, int);
889 internal_proto(write_b);
891 extern void write_d (st_parameter_dt *, const fnode *, const char *, int);
892 internal_proto(write_d);
894 extern void write_e (st_parameter_dt *, const fnode *, const char *, int);
895 internal_proto(write_e);
897 extern void write_en (st_parameter_dt *, const fnode *, const char *, int);
898 internal_proto(write_en);
900 extern void write_es (st_parameter_dt *, const fnode *, const char *, int);
901 internal_proto(write_es);
903 extern void write_f (st_parameter_dt *, const fnode *, const char *, int);
904 internal_proto(write_f);
906 extern void write_i (st_parameter_dt *, const fnode *, const char *, int);
907 internal_proto(write_i);
909 extern void write_l (st_parameter_dt *, const fnode *, char *, int);
910 internal_proto(write_l);
912 extern void write_o (st_parameter_dt *, const fnode *, const char *, int);
913 internal_proto(write_o);
915 extern void write_x (st_parameter_dt *, int, int);
916 internal_proto(write_x);
918 extern void write_z (st_parameter_dt *, const fnode *, const char *, int);
919 internal_proto(write_z);
921 extern void list_formatted_write (st_parameter_dt *, bt, void *, int, size_t,
923 internal_proto(list_formatted_write);
925 /* size_from_kind.c */
926 extern size_t size_from_real_kind (int);
927 internal_proto(size_from_real_kind);
929 extern size_t size_from_complex_kind (int);
930 internal_proto(size_from_complex_kind);
933 extern void free_ionml (st_parameter_dt *);
934 internal_proto(free_ionml);
937 inc_waiting_locked (gfc_unit *u)
939 #ifdef HAVE_SYNC_FETCH_AND_ADD
940 (void) __sync_fetch_and_add (&u->waiting, 1);
947 predec_waiting_locked (gfc_unit *u)
949 #ifdef HAVE_SYNC_FETCH_AND_ADD
950 return __sync_add_and_fetch (&u->waiting, -1);
957 dec_waiting_unlocked (gfc_unit *u)
959 #ifdef HAVE_SYNC_FETCH_AND_ADD
960 (void) __sync_fetch_and_add (&u->waiting, -1);
962 __gthread_mutex_lock (&unit_lock);
964 __gthread_mutex_unlock (&unit_lock);