OSDN Git Service

* io/list_read.c (nml_parse_qualifier): Use memcpy to extract
[pf3gnuchains/gcc-fork.git] / libgfortran / io / io.h
1 /* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
2    Contributed by Andy Vaught
3
4 This file is part of the GNU Fortran 95 runtime library (libgfortran).
5
6 Libgfortran is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 Libgfortran is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Libgfortran; see the file COPYING.  If not, write to
18 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.  */
20
21 /* As a special exception, if you link this library with other files,
22    some of which are compiled with GCC, to produce an executable,
23    this library does not by itself cause the resulting executable
24    to be covered by the GNU General Public License.
25    This exception does not however invalidate any other reasons why
26    the executable file might be covered by the GNU General Public License.  */
27
28 #ifndef GFOR_IO_H
29 #define GFOR_IO_H
30
31 /* IO library include.  */
32
33 #include <setjmp.h>
34 #include "libgfortran.h"
35 #ifdef HAVE_PRAGMA_WEAK
36 /* Used by gthr.h.  */
37 #define SUPPORTS_WEAK 1
38 #endif
39
40 #ifdef _AIX
41 #undef _LARGE_FILES
42 #define _LARGE_FILE_API
43 #endif
44
45 #include <gthr.h>
46
47 #define DEFAULT_TEMPDIR "/tmp"
48
49 /* Basic types used in data transfers.  */
50
51 typedef enum
52 { BT_NULL, BT_INTEGER, BT_LOGICAL, BT_CHARACTER, BT_REAL,
53   BT_COMPLEX
54 }
55 bt;
56
57
58 typedef enum
59 { SUCCESS = 1, FAILURE }
60 try;
61
62 struct st_parameter_dt;
63
64 typedef struct stream
65 {
66   char *(*alloc_w_at) (struct stream *, int *, gfc_offset);
67   char *(*alloc_r_at) (struct stream *, int *, gfc_offset);
68   try (*sfree) (struct stream *);
69   try (*close) (struct stream *);
70   try (*seek) (struct stream *, gfc_offset);
71   try (*truncate) (struct stream *);
72   int (*read) (struct stream *, void *, size_t *);
73   int (*write) (struct stream *, const void *, size_t *);
74 }
75 stream;
76
77
78 /* Macros for doing file I/O given a stream.  */
79
80 #define sfree(s) ((s)->sfree)(s)
81 #define sclose(s) ((s)->close)(s)
82
83 #define salloc_r(s, len) ((s)->alloc_r_at)(s, len, -1)
84 #define salloc_w(s, len) ((s)->alloc_w_at)(s, len, -1)
85
86 #define salloc_r_at(s, len, where) ((s)->alloc_r_at)(s, len, where)
87 #define salloc_w_at(s, len, where) ((s)->alloc_w_at)(s, len, where)
88
89 #define sseek(s, pos) ((s)->seek)(s, pos)
90 #define struncate(s) ((s)->truncate)(s)
91 #define sread(s, buf, nbytes) ((s)->read)(s, buf, nbytes)
92 #define swrite(s, buf, nbytes) ((s)->write)(s, buf, nbytes)
93
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
96    is used.  */
97
98 typedef struct array_loop_spec
99 {
100   /* Index counter for this dimension.  */
101   ssize_t idx;
102
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 }
112 array_loop_spec;
113
114 /* Representation of a namelist object in libgfortran
115
116    Namelist Records
117       &GROUPNAME  OBJECT=value[s] [,OBJECT=value[s]].../
118      or
119       &GROUPNAME  OBJECT=value[s] [,OBJECT=value[s]]...&END
120
121    The object can be a fully qualified, compound name for an instrinsic
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
131    arrays.  */
132
133 typedef struct namelist_type
134 {
135
136   /* Object type, stored as GFC_DTYPE_xxxx.  */
137   bt type;
138
139   /* Object name.  */
140   char * var_name;
141
142   /* Address for the start of the object's data.  */
143   void * mem_pos;
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.  */
149   int len;
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;
161   array_loop_spec * ls;
162   struct namelist_type * next;
163 }
164 namelist_info;
165
166 /* Options for the OPEN statement.  */
167
168 typedef enum
169 { ACCESS_SEQUENTIAL, ACCESS_DIRECT, ACCESS_APPEND,
170   ACCESS_UNSPECIFIED
171 }
172 unit_access;
173
174 typedef enum
175 { ACTION_READ, ACTION_WRITE, ACTION_READWRITE,
176   ACTION_UNSPECIFIED
177 }
178 unit_action;
179
180 typedef enum
181 { BLANK_NULL, BLANK_ZERO, BLANK_UNSPECIFIED }
182 unit_blank;
183
184 typedef enum
185 { DELIM_NONE, DELIM_APOSTROPHE, DELIM_QUOTE,
186   DELIM_UNSPECIFIED
187 }
188 unit_delim;
189
190 typedef enum
191 { FORM_FORMATTED, FORM_UNFORMATTED, FORM_UNSPECIFIED }
192 unit_form;
193
194 typedef enum
195 { POSITION_ASIS, POSITION_REWIND, POSITION_APPEND,
196   POSITION_UNSPECIFIED
197 }
198 unit_position;
199
200 typedef enum
201 { STATUS_UNKNOWN, STATUS_OLD, STATUS_NEW, STATUS_SCRATCH,
202   STATUS_REPLACE, STATUS_UNSPECIFIED
203 }
204 unit_status;
205
206 typedef enum
207 { PAD_YES, PAD_NO, PAD_UNSPECIFIED }
208 unit_pad;
209
210 typedef enum
211 { ADVANCE_YES, ADVANCE_NO, ADVANCE_UNSPECIFIED }
212 unit_advance;
213
214 typedef enum
215 {READING, WRITING}
216 unit_mode;
217
218 #define CHARACTER1(name) \
219               char * name; \
220               gfc_charlen_type name ## _len
221 #define CHARACTER2(name) \
222               gfc_charlen_type name ## _len; \
223               char * name
224
225 #define IOPARM_LIBRETURN_MASK           (3 << 0)
226 #define IOPARM_LIBRETURN_OK             (0 << 0)
227 #define IOPARM_LIBRETURN_ERROR          (1 << 0)
228 #define IOPARM_LIBRETURN_END            (2 << 0)
229 #define IOPARM_LIBRETURN_EOR            (3 << 0)
230 #define IOPARM_ERR                      (1 << 2)
231 #define IOPARM_END                      (1 << 3)
232 #define IOPARM_EOR                      (1 << 4)
233 #define IOPARM_HAS_IOSTAT               (1 << 5)
234 #define IOPARM_HAS_IOMSG                (1 << 6)
235
236 #define IOPARM_COMMON_MASK              ((1 << 7) - 1)
237
238 typedef struct st_parameter_common
239 {
240   GFC_INTEGER_4 flags;
241   GFC_INTEGER_4 unit;
242   const char *filename;
243   GFC_INTEGER_4 line;
244   CHARACTER2 (iomsg);
245   GFC_INTEGER_4 *iostat;
246 }
247 st_parameter_common;
248
249 #define IOPARM_OPEN_HAS_RECL_IN         (1 << 7)
250 #define IOPARM_OPEN_HAS_FILE            (1 << 8)
251 #define IOPARM_OPEN_HAS_STATUS          (1 << 9)
252 #define IOPARM_OPEN_HAS_ACCESS          (1 << 10)
253 #define IOPARM_OPEN_HAS_FORM            (1 << 11)
254 #define IOPARM_OPEN_HAS_BLANK           (1 << 12)
255 #define IOPARM_OPEN_HAS_POSITION        (1 << 13)
256 #define IOPARM_OPEN_HAS_ACTION          (1 << 14)
257 #define IOPARM_OPEN_HAS_DELIM           (1 << 15)
258 #define IOPARM_OPEN_HAS_PAD             (1 << 16)
259
260 typedef struct
261 {
262   st_parameter_common common;
263   GFC_INTEGER_4 recl_in;
264   CHARACTER2 (file);
265   CHARACTER1 (status);
266   CHARACTER2 (access);
267   CHARACTER1 (form);
268   CHARACTER2 (blank);
269   CHARACTER1 (position);
270   CHARACTER2 (action);
271   CHARACTER1 (delim);
272   CHARACTER2 (pad);
273 }
274 st_parameter_open;
275
276 #define IOPARM_CLOSE_HAS_STATUS         (1 << 7)
277
278 typedef struct
279 {
280   st_parameter_common common;
281   CHARACTER1 (status);
282 }
283 st_parameter_close;
284
285 typedef struct
286 {
287   st_parameter_common common;
288 }
289 st_parameter_filepos;
290
291 #define IOPARM_INQUIRE_HAS_EXIST        (1 << 7)
292 #define IOPARM_INQUIRE_HAS_OPENED       (1 << 8)
293 #define IOPARM_INQUIRE_HAS_NUMBER       (1 << 9)
294 #define IOPARM_INQUIRE_HAS_NAMED        (1 << 10)
295 #define IOPARM_INQUIRE_HAS_NEXTREC      (1 << 11)
296 #define IOPARM_INQUIRE_HAS_RECL_OUT     (1 << 12)
297 #define IOPARM_INQUIRE_HAS_FILE         (1 << 13)
298 #define IOPARM_INQUIRE_HAS_ACCESS       (1 << 14)
299 #define IOPARM_INQUIRE_HAS_FORM         (1 << 15)
300 #define IOPARM_INQUIRE_HAS_BLANK        (1 << 16)
301 #define IOPARM_INQUIRE_HAS_POSITION     (1 << 17)
302 #define IOPARM_INQUIRE_HAS_ACTION       (1 << 18)
303 #define IOPARM_INQUIRE_HAS_DELIM        (1 << 19)
304 #define IOPARM_INQUIRE_HAS_PAD          (1 << 20)
305 #define IOPARM_INQUIRE_HAS_NAME         (1 << 21)
306 #define IOPARM_INQUIRE_HAS_SEQUENTIAL   (1 << 22)
307 #define IOPARM_INQUIRE_HAS_DIRECT       (1 << 23)
308 #define IOPARM_INQUIRE_HAS_FORMATTED    (1 << 24)
309 #define IOPARM_INQUIRE_HAS_UNFORMATTED  (1 << 25)
310 #define IOPARM_INQUIRE_HAS_READ         (1 << 26)
311 #define IOPARM_INQUIRE_HAS_WRITE        (1 << 27)
312 #define IOPARM_INQUIRE_HAS_READWRITE    (1 << 28)
313
314 typedef struct
315 {
316   st_parameter_common common;
317   GFC_INTEGER_4 *exist, *opened, *number, *named;
318   GFC_INTEGER_4 *nextrec, *recl_out;
319   CHARACTER1 (file);
320   CHARACTER2 (access);
321   CHARACTER1 (form);
322   CHARACTER2 (blank);
323   CHARACTER1 (position);
324   CHARACTER2 (action);
325   CHARACTER1 (delim);
326   CHARACTER2 (pad);
327   CHARACTER1 (name);
328   CHARACTER2 (sequential);
329   CHARACTER1 (direct);
330   CHARACTER2 (formatted);
331   CHARACTER1 (unformatted);
332   CHARACTER2 (read);
333   CHARACTER1 (write);
334   CHARACTER2 (readwrite);
335 }
336 st_parameter_inquire;
337
338 struct gfc_unit;
339 struct format_data;
340
341 #define IOPARM_DT_LIST_FORMAT                   (1 << 7)
342 #define IOPARM_DT_NAMELIST_READ_MODE            (1 << 8)
343 #define IOPARM_DT_HAS_REC                       (1 << 9)
344 #define IOPARM_DT_HAS_SIZE                      (1 << 10)
345 #define IOPARM_DT_HAS_IOLENGTH                  (1 << 11)
346 #define IOPARM_DT_HAS_FORMAT                    (1 << 12)
347 #define IOPARM_DT_HAS_ADVANCE                   (1 << 13)
348 #define IOPARM_DT_HAS_INTERNAL_UNIT             (1 << 14)
349 #define IOPARM_DT_HAS_NAMELIST_NAME             (1 << 15)
350 /* Internal use bit.  */
351 #define IOPARM_DT_IONML_SET                     (1 << 31)
352
353 typedef struct st_parameter_dt
354 {
355   st_parameter_common common;
356   GFC_INTEGER_4 rec;
357   GFC_INTEGER_4 *size, *iolength;
358   gfc_array_char *internal_unit_desc;
359   CHARACTER1 (format);
360   CHARACTER2 (advance);
361   CHARACTER1 (internal_unit);
362   CHARACTER2 (namelist_name);
363   /* Private part of the structure.  The compiler just needs
364      to reserve enough space.  */
365   union
366     {
367       struct
368         {
369           void (*transfer) (struct st_parameter_dt *, bt, void *, int,
370                             size_t, size_t);
371           struct gfc_unit *current_unit;
372           int item_count; /* Item number in a formatted data transfer.  */
373           unit_mode mode;
374           unit_blank blank_status;
375           enum {SIGN_S, SIGN_SS, SIGN_SP} sign_status;
376           int scale_factor;
377           int max_pos; /* Maximum righthand column written to.  */
378           /* Number of skips + spaces to be done for T and X-editing.  */
379           int skips;
380           /* Number of spaces to be done for T and X-editing.  */
381           int pending_spaces;
382           unit_advance advance_status;
383
384           unsigned reversion_flag : 1; /* Format reversion has occurred.  */
385           unsigned first_item : 1;
386           unsigned seen_dollar : 1;
387           unsigned sf_seen_eor : 1;
388           unsigned eor_condition : 1;
389           unsigned no_leading_blank : 1;
390           unsigned char_flag : 1;
391           unsigned input_complete : 1;
392           unsigned at_eol : 1;
393           unsigned comma_flag : 1;
394           /* A namelist specific flag used in the list directed library
395              to flag that calls are being made from namelist read (eg. to
396              ignore comments or to treat '/' as a terminator)  */
397           unsigned namelist_mode : 1;
398           /* A namelist specific flag used in the list directed library
399              to flag read errors and return, so that an attempt can be
400              made to read a new object name.  */
401           unsigned nml_read_error : 1;
402           /* 20 unused bits.  */
403
404           char last_char;
405           char nml_delim;
406
407           int repeat_count;
408           int saved_length;
409           int saved_used;
410           bt saved_type;
411           char *saved_string;
412           char *scratch;
413           char *line_buffer;
414           struct format_data *fmt;
415           jmp_buf *eof_jump;
416           namelist_info *ionml;
417
418           /* Storage area for values except for strings.  Must be large
419              enough to hold a complex value (two reals) of the largest
420              kind.  */
421           char value[32];
422         } p;
423       char pad[16 * sizeof (char *) + 32 * sizeof (int)];
424     } u;
425 }
426 st_parameter_dt;
427
428 #undef CHARACTER1
429 #undef CHARACTER2
430
431 typedef struct
432 {
433   unit_access access;
434   unit_action action;
435   unit_blank blank;
436   unit_delim delim;
437   unit_form form;
438   int is_notpadded;
439   unit_position position;
440   unit_status status;
441   unit_pad pad;
442 }
443 unit_flags;
444
445
446 /* The default value of record length for preconnected units is defined
447    here. This value can be overriden by an environment variable.
448    Default value is 1 Gb.  */
449
450 #define DEFAULT_RECL 1073741824
451
452
453 typedef struct gfc_unit
454 {
455   int unit_number;
456   stream *s;
457   
458   /* Treap links.  */
459   struct gfc_unit *left, *right;
460   int priority;
461
462   int read_bad, current_record;
463   enum
464   { NO_ENDFILE, AT_ENDFILE, AFTER_ENDFILE }
465   endfile;
466
467   unit_mode mode;
468   unit_flags flags;
469
470   /* recl           -- Record length of the file.
471      last_record    -- Last record number read or written
472      maxrec         -- Maximum record number in a direct access file
473      bytes_left     -- Bytes left in current record.  */
474   gfc_offset recl, last_record, maxrec, bytes_left;
475
476   __gthread_mutex_t lock;
477   /* Number of threads waiting to acquire this unit's lock.
478      When non-zero, close_unit doesn't only removes the unit
479      from the UNIT_ROOT tree, but doesn't free it and the
480      last of the waiting threads will do that.
481      This must be either atomically increased/decreased, or
482      always guarded by UNIT_LOCK.  */
483   int waiting;
484   /* Flag set by close_unit if the unit as been closed.
485      Must be manipulated under unit's lock.  */
486   int closed;
487
488   /* For traversing arrays */
489   array_loop_spec *ls;
490   int rank;
491
492   int file_len;
493   char *file;
494 }
495 gfc_unit;
496
497 /* Format tokens.  Only about half of these can be stored in the
498    format nodes.  */
499
500 typedef enum
501 {
502   FMT_NONE = 0, FMT_UNKNOWN, FMT_SIGNED_INT, FMT_ZERO, FMT_POSINT, FMT_PERIOD,
503   FMT_COMMA, FMT_COLON, FMT_SLASH, FMT_DOLLAR, FMT_T, FMT_TR, FMT_TL,
504   FMT_LPAREN, FMT_RPAREN, FMT_X, FMT_S, FMT_SS, FMT_SP, FMT_STRING,
505   FMT_BADSTRING, FMT_P, FMT_I, FMT_B, FMT_BN, FMT_BZ, FMT_O, FMT_Z, FMT_F,
506   FMT_E, FMT_EN, FMT_ES, FMT_G, FMT_L, FMT_A, FMT_D, FMT_H, FMT_END
507 }
508 format_token;
509
510
511 /* Format nodes.  A format string is converted into a tree of these
512    structures, which is traversed as part of a data transfer statement.  */
513
514 typedef struct fnode
515 {
516   format_token format;
517   int repeat;
518   struct fnode *next;
519   char *source;
520
521   union
522   {
523     struct
524     {
525       int w, d, e;
526     }
527     real;
528
529     struct
530     {
531       int length;
532       char *p;
533     }
534     string;
535
536     struct
537     {
538       int w, m;
539     }
540     integer;
541
542     int w;
543     int k;
544     int r;
545     int n;
546
547     struct fnode *child;
548   }
549   u;
550
551   /* Members for traversing the tree during data transfer.  */
552
553   int count;
554   struct fnode *current;
555
556 }
557 fnode;
558
559
560 /* unix.c */
561
562 extern int move_pos_offset (stream *, int);
563 internal_proto(move_pos_offset);
564
565 extern int compare_files (stream *, stream *);
566 internal_proto(compare_files);
567
568 extern stream *open_external (st_parameter_open *, unit_flags *);
569 internal_proto(open_external);
570
571 extern stream *open_internal (char *, int);
572 internal_proto(open_internal);
573
574 extern stream *input_stream (void);
575 internal_proto(input_stream);
576
577 extern stream *output_stream (void);
578 internal_proto(output_stream);
579
580 extern stream *error_stream (void);
581 internal_proto(error_stream);
582
583 extern int compare_file_filename (gfc_unit *, const char *, int);
584 internal_proto(compare_file_filename);
585
586 extern gfc_unit *find_file (const char *file, gfc_charlen_type file_len);
587 internal_proto(find_file);
588
589 extern void flush_all_units (void);
590 internal_proto(flush_all_units);
591
592 extern int stream_at_bof (stream *);
593 internal_proto(stream_at_bof);
594
595 extern int stream_at_eof (stream *);
596 internal_proto(stream_at_eof);
597
598 extern int delete_file (gfc_unit *);
599 internal_proto(delete_file);
600
601 extern int file_exists (const char *file, gfc_charlen_type file_len);
602 internal_proto(file_exists);
603
604 extern const char *inquire_sequential (const char *, int);
605 internal_proto(inquire_sequential);
606
607 extern const char *inquire_direct (const char *, int);
608 internal_proto(inquire_direct);
609
610 extern const char *inquire_formatted (const char *, int);
611 internal_proto(inquire_formatted);
612
613 extern const char *inquire_unformatted (const char *, int);
614 internal_proto(inquire_unformatted);
615
616 extern const char *inquire_read (const char *, int);
617 internal_proto(inquire_read);
618
619 extern const char *inquire_write (const char *, int);
620 internal_proto(inquire_write);
621
622 extern const char *inquire_readwrite (const char *, int);
623 internal_proto(inquire_readwrite);
624
625 extern gfc_offset file_length (stream *);
626 internal_proto(file_length);
627
628 extern gfc_offset file_position (stream *);
629 internal_proto(file_position);
630
631 extern int is_seekable (stream *);
632 internal_proto(is_seekable);
633
634 extern int is_preconnected (stream *);
635 internal_proto(is_preconnected);
636
637 extern void flush_if_preconnected (stream *);
638 internal_proto(flush_if_preconnected);
639
640 extern void empty_internal_buffer(stream *);
641 internal_proto(empty_internal_buffer);
642
643 extern try flush (stream *);
644 internal_proto(flush);
645
646 extern int stream_isatty (stream *);
647 internal_proto(stream_isatty);
648
649 extern char * stream_ttyname (stream *);
650 internal_proto(stream_ttyname);
651
652 extern gfc_offset stream_offset (stream *s);
653 internal_proto(stream_offset);
654
655 extern int unit_to_fd (int);
656 internal_proto(unit_to_fd);
657
658 extern int unpack_filename (char *, const char *, int);
659 internal_proto(unpack_filename);
660
661 /* unit.c */
662
663 /* Maximum file offset, computed at library initialization time.  */
664 extern gfc_offset max_offset;
665 internal_proto(max_offset);
666
667 /* Unit tree root.  */
668 extern gfc_unit *unit_root;
669 internal_proto(unit_root);
670
671 extern __gthread_mutex_t unit_lock;
672 internal_proto(unit_lock);
673
674 extern int close_unit (gfc_unit *);
675 internal_proto(close_unit);
676
677 extern int is_internal_unit (st_parameter_dt *);
678 internal_proto(is_internal_unit);
679
680 extern int is_array_io (st_parameter_dt *);
681 internal_proto(is_array_io);
682
683 extern gfc_unit *find_unit (int);
684 internal_proto(find_unit);
685
686 extern gfc_unit *find_or_create_unit (int);
687 internal_proto(find_unit);
688
689 extern gfc_unit *get_unit (st_parameter_dt *, int);
690 internal_proto(get_unit);
691
692 extern void unlock_unit (gfc_unit *);
693 internal_proto(unlock_unit);
694
695 /* open.c */
696
697 extern void test_endfile (gfc_unit *);
698 internal_proto(test_endfile);
699
700 extern gfc_unit *new_unit (st_parameter_open *, gfc_unit *, unit_flags *);
701 internal_proto(new_unit);
702
703 /* format.c */
704
705 extern void parse_format (st_parameter_dt *);
706 internal_proto(parse_format);
707
708 extern const fnode *next_format (st_parameter_dt *);
709 internal_proto(next_format);
710
711 extern void unget_format (st_parameter_dt *, const fnode *);
712 internal_proto(unget_format);
713
714 extern void format_error (st_parameter_dt *, const fnode *, const char *);
715 internal_proto(format_error);
716
717 extern void free_format_data (st_parameter_dt *);
718 internal_proto(free_format_data);
719
720 /* transfer.c */
721
722 #define SCRATCH_SIZE 300
723
724 extern const char *type_name (bt);
725 internal_proto(type_name);
726
727 extern void *read_block (st_parameter_dt *, int *);
728 internal_proto(read_block);
729
730 extern void *write_block (st_parameter_dt *, int);
731 internal_proto(write_block);
732
733 extern gfc_offset next_array_record (st_parameter_dt *, array_loop_spec *);
734 internal_proto(next_array_record);
735
736 extern gfc_offset init_loop_spec (gfc_array_char *, array_loop_spec *);
737 internal_proto(init_loop_spec);
738
739 extern void next_record (st_parameter_dt *, int);
740 internal_proto(next_record);
741
742 /* read.c */
743
744 extern void set_integer (void *, GFC_INTEGER_LARGEST, int);
745 internal_proto(set_integer);
746
747 extern GFC_UINTEGER_LARGEST max_value (int, int);
748 internal_proto(max_value);
749
750 extern int convert_real (st_parameter_dt *, void *, const char *, int);
751 internal_proto(convert_real);
752
753 extern void read_a (st_parameter_dt *, const fnode *, char *, int);
754 internal_proto(read_a);
755
756 extern void read_f (st_parameter_dt *, const fnode *, char *, int);
757 internal_proto(read_f);
758
759 extern void read_l (st_parameter_dt *, const fnode *, char *, int);
760 internal_proto(read_l);
761
762 extern void read_x (st_parameter_dt *, int);
763 internal_proto(read_x);
764
765 extern void read_radix (st_parameter_dt *, const fnode *, char *, int, int);
766 internal_proto(read_radix);
767
768 extern void read_decimal (st_parameter_dt *, const fnode *, char *, int);
769 internal_proto(read_decimal);
770
771 /* list_read.c */
772
773 extern void list_formatted_read (st_parameter_dt *, bt, void *, int, size_t,
774                                  size_t);
775 internal_proto(list_formatted_read);
776
777 extern void finish_list_read (st_parameter_dt *);
778 internal_proto(finish_list_read);
779
780 extern void namelist_read (st_parameter_dt *);
781 internal_proto(namelist_read);
782
783 extern void namelist_write (st_parameter_dt *);
784 internal_proto(namelist_write);
785
786 /* write.c */
787
788 extern void write_a (st_parameter_dt *, const fnode *, const char *, int);
789 internal_proto(write_a);
790
791 extern void write_b (st_parameter_dt *, const fnode *, const char *, int);
792 internal_proto(write_b);
793
794 extern void write_d (st_parameter_dt *, const fnode *, const char *, int);
795 internal_proto(write_d);
796
797 extern void write_e (st_parameter_dt *, const fnode *, const char *, int);
798 internal_proto(write_e);
799
800 extern void write_en (st_parameter_dt *, const fnode *, const char *, int);
801 internal_proto(write_en);
802
803 extern void write_es (st_parameter_dt *, const fnode *, const char *, int);
804 internal_proto(write_es);
805
806 extern void write_f (st_parameter_dt *, const fnode *, const char *, int);
807 internal_proto(write_f);
808
809 extern void write_i (st_parameter_dt *, const fnode *, const char *, int);
810 internal_proto(write_i);
811
812 extern void write_l (st_parameter_dt *, const fnode *, char *, int);
813 internal_proto(write_l);
814
815 extern void write_o (st_parameter_dt *, const fnode *, const char *, int);
816 internal_proto(write_o);
817
818 extern void write_x (st_parameter_dt *, int, int);
819 internal_proto(write_x);
820
821 extern void write_z (st_parameter_dt *, const fnode *, const char *, int);
822 internal_proto(write_z);
823
824 extern void list_formatted_write (st_parameter_dt *, bt, void *, int, size_t,
825                                   size_t);
826 internal_proto(list_formatted_write);
827
828 /* error.c */
829 extern try notify_std (int, const char *);
830 internal_proto(notify_std);
831
832 /* size_from_kind.c */
833 extern size_t size_from_real_kind (int);
834 internal_proto(size_from_real_kind);
835
836 extern size_t size_from_complex_kind (int);
837 internal_proto(size_from_complex_kind);
838
839 /* lock.c */
840 extern void free_ionml (st_parameter_dt *);
841 internal_proto(free_ionml);
842
843 static inline void
844 inc_waiting_locked (gfc_unit *u)
845 {
846 #ifdef HAVE_SYNC_FETCH_AND_ADD
847   (void) __sync_fetch_and_add (&u->waiting, 1);
848 #else
849   u->waiting++;
850 #endif
851 }
852
853 static inline int
854 predec_waiting_locked (gfc_unit *u)
855 {
856 #ifdef HAVE_SYNC_FETCH_AND_ADD
857   return __sync_add_and_fetch (&u->waiting, -1);
858 #else
859   return --u->waiting;
860 #endif
861 }
862
863 static inline void
864 dec_waiting_unlocked (gfc_unit *u)
865 {
866 #ifdef HAVE_SYNC_FETCH_AND_ADD
867   (void) __sync_fetch_and_add (&u->waiting, -1);
868 #else
869   __gthread_mutex_lock (&unit_lock);
870   u->waiting--;
871   __gthread_mutex_unlock (&unit_lock);
872 #endif
873 }
874
875 #endif