Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2.1 of the GNU Lesser General Public License 00007 as published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU Lesser General Public 00021 License along with this program; if not, write the Free Software 00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 00023 USA. 00024 00025 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00026 Mountain View, CA 94043, or: 00027 00028 http://www.sgi.com 00029 00030 For further information regarding this notice, see: 00031 00032 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00033 00034 */ 00035 00036 00037 /* USMID @(#) libf/include/fio.h 92.6 08/02/99 10:40:42 */ 00038 00039 #ifndef _FIO_H 00040 #define _FIO_H 00041 00042 #include "fstats.h" 00043 #include <errno.h> 00044 #include <ffio.h> 00045 #include <fortran.h> 00046 #ifdef _UNICOS 00047 #include <procstat.h> 00048 #endif 00049 #include <stdio.h> 00050 #include <sys/types.h> 00051 #if defined(_UNICOS) || defined(_SOLARIS) 00052 #include <sys/iosw.h> 00053 #endif 00054 #include <cray/assign.h> 00055 #include <cray/fndc.h> 00056 #include <cray/format.h> 00057 #include <cray/fortio.h> /* For unum_t and recn_t */ 00058 #include <cray/mtlock.h> 00059 #include <cray/dopevec.h> 00060 #include <cray/nassert.h> 00061 #include <cray/portdefs.h> 00062 #ifdef _CRAYMPP 00063 #include <signal.h> 00064 #endif 00065 00066 /************************************************************************ 00067 * 00068 * Debug control 00069 * 00070 ***********************************************************************/ 00071 00072 #ifdef LIBDEBUG 00073 #define _ASSERT_ON 1 /* turn on assertion checking */ 00074 #define DEBUG_MTIO 1 /* unconditional use of locks */ 00075 #endif 00076 00077 #define PRINT_TIP(tipa) { \ 00078 fprintf(stderr, "tip address = %o\n", tipa); \ 00079 fprintf(stderr, " type90 = %d\n", (tipa)->type90); \ 00080 fprintf(stderr, " type77 = %d\n", (tipa)->type77); \ 00081 fprintf(stderr, " intlen = %d\n", (tipa)->intlen); \ 00082 fprintf(stderr, " extlen = %d\n", (tipa)->extlen); \ 00083 fprintf(stderr, " cnvindx = %d\n", (tipa)->cnvindx); \ 00084 fprintf(stderr, " count = %ld\n", (tipa)->count); \ 00085 fprintf(stderr, " stride = %ld\n", (tipa)->stride); \ 00086 fprintf(stderr, " elsize = %d\n", (tipa)->elsize); \ 00087 if ((tipa)->cnvindx) { \ 00088 fprintf(stderr, " newfunc = %d\n", (tipa)->newfunc);\ 00089 fprintf(stderr, " cnvtype = %d\n", (tipa)->cnvtype);\ 00090 fprintf(stderr, " cnvfunc = %o\n", (tipa)->cnvfunc);\ 00091 } \ 00092 } 00093 00094 /************************************************************************ 00095 * 00096 * Constants 00097 * 00098 ***********************************************************************/ 00099 00100 #define HASH_SIZE 256 /* must be a power of 2 */ 00101 00102 #define STDIN_U 100 /* Special stdin unit */ 00103 #define STDOUT_U 101 /* Special stdout unit */ 00104 #define STDERR_U 102 /* Special stderr unit */ 00105 00106 #define RECMAX 1024 /* Default (initial) size of line buffer */ 00107 #define RECMAXLDO 133 /* List-directed output line length */ 00108 00109 #define ERROR 1 00110 #define OK 0 00111 #define YES 1 00112 #define NO 0 00113 00114 #define WRITE 1 /* write */ 00115 #define READ 2 /* read */ 00116 #define SEQ 3 /* sequential access */ 00117 #define DIR 4 /* direct access */ 00118 #define FMT 5 /* formatted */ 00119 #define UNF 6 /* unformatted */ 00120 #define EXT 7 /* external */ 00121 #define INT 8 /* internal */ 00122 00123 /* 00124 * Types of I/O statements 00125 */ 00126 /* flags folded into the statement code */ 00127 00128 #define TF_WRITE 001 /* write statement */ 00129 #define TF_READ 002 /* read statement */ 00130 #define TF_POS 004 /* statement which might reposition a file */ 00131 #define TF_FMT 010 /* formatted read or write statement */ 00132 00133 /* statement codes */ 00134 00135 #define T_WSF (00100 | TF_WRITE | TF_POS | TF_FMT ) 00136 #define T_WSU (00200 | TF_WRITE | TF_POS ) 00137 #define T_WDF (00300 | TF_WRITE | TF_POS | TF_FMT ) 00138 #define T_WDU (00400 | TF_WRITE | TF_POS ) 00139 #define T_WLIST (00500 | TF_WRITE | TF_POS ) 00140 #define T_WNL (00600 | TF_WRITE | TF_POS ) 00141 00142 #define T_RSF (00700 | TF_READ | TF_POS | TF_FMT ) 00143 #define T_RSU (01100 | TF_READ | TF_POS ) 00144 #define T_RDF (01200 | TF_READ | TF_POS | TF_FMT ) 00145 #define T_RDU (01300 | TF_READ | TF_POS ) 00146 #define T_RLIST (01400 | TF_READ | TF_POS ) 00147 #define T_RNL (01500 | TF_READ | TF_POS ) 00148 00149 #define T_BUFOUT (01600 | TF_POS ) 00150 #define T_BUFIN (01700 | TF_POS ) 00151 00152 #define T_OPEN (02000 ) 00153 #define T_REWIND (02100 | TF_POS ) 00154 #define T_BACKSPACE (02200 | TF_POS ) 00155 #define T_ENDFILE (02300 | TF_POS ) 00156 #define T_CLOSE (02400 ) 00157 #define T_INQF (02500 ) 00158 #define T_INQU (02600 ) 00159 00160 #define T_MISC (02700 | TF_POS ) 00161 00162 #define T_GETPOS (03000 ) 00163 #define T_SETPOS (03100 | TF_POS ) 00164 #define T_LENGTH (03200 ) 00165 #define T_UNIT (03300 ) 00166 #define T_TAPE (03400 | TF_POS ) 00167 #define T_FLUSH (03500 ) 00168 #define T_NUMBLKS (03600 ) 00169 00170 /* 00171 * Fortran 77 data types 00172 */ 00173 00174 #define DT_NONE 0 /* Typeless */ 00175 #define DT_INT 1 /* Integer */ 00176 #define DT_REAL 2 /* Real */ 00177 #define DT_DBLE 3 /* Double */ 00178 #define DT_CMPLX 4 /* Complex */ 00179 #define DT_LOG 5 /* Logical */ 00180 #define DT_CHAR 6 /* Character */ 00181 #define DT_SINT 7 /* Short integer */ 00182 #define DT_DBLCOM 8 /* Double complex (intended for fortran 00183 90 support, but never used) */ 00184 #define DT_MAX 9 /* Number of data types */ 00185 00186 /* 00187 * Fortran I/O buffer size constants. 00188 */ 00189 00190 #define BLKSIZE 4096 /* Bytes in a 512-word disk block */ 00191 #define SECTOR BLKSIZE /* Temporary synonym for BLKSIZE */ 00192 #ifdef _UNICOS 00193 #define DEF_BIN_BS _VALUE(_def_bin_bs) 00194 #define DEF_SBIN_BS _VALUE(_def_sbin_bs) 00195 #else 00196 #define DEF_BIN_BS 1 00197 #define DEF_SBIN_BS 1 00198 #endif 00199 00200 #ifdef _CRAYMPP 00201 /* Values used when running on mppsim in user virtual mode */ 00202 #define DEF_BINSIM_BS 1 00203 #define DEF_SBINSIM_BS 1 00204 #endif 00205 00206 #define DFBUFSZ 8 /* Direct formatted buffer size */ 00207 #define SFBUFSZ 8 /* Sequential formatted buffer size */ 00208 #if defined(__mips) || defined(_LITTLE_ENDIAN) 00209 /* We choose this direct unformatted */ 00210 /* buffer size to match MIPS f77 */ 00211 #define DUBUFSZ 16 /* Direct unformatted buffer size */ 00212 #else 00213 #define DUBUFSZ 8 /* Direct unformatted buffer size */ 00214 #endif 00215 #define SUBUFSZ 48 /* Sequential unformatted buffer size */ 00216 00217 #define DEFAULT_NBUF 4 /* Default no. of direct-access buffers */ 00218 00219 /* Temporary buffer size for packing/unpacking line buffers */ 00220 00221 #ifdef _MAXVL 00222 #define TBUFSZW _MAXVL 00223 #else 00224 #define TBUFSZW 36 00225 #endif 00226 00227 #define TBUFSZB (TBUFSZW * sizeof(long)) 00228 00229 #define CHBUFSIZE (1024 * sizeof(long)) /* chunking buf size (bytes) */ 00230 00231 /* 00232 * CFT77 return status values (set in S3 on return) 00233 */ 00234 00235 #define IO_OKAY 0 /* Normal completion */ 00236 #define IO_ERR 1 /* Error status */ 00237 #define IO_END 2 /* End status */ 00238 00239 /* 00240 * Fortran I/O completion status 00241 */ 00242 00243 #define CNT 1 /* Count exhausted */ 00244 #define EOR 0 /* End-of-record */ 00245 #ifndef EOF 00246 #define EOF -1 /* End-of-file */ 00247 #endif 00248 #define EOD -2 /* End-of-data */ 00249 00250 #define IOERR -1 /* Fortran I/O error */ 00251 00252 /* 00253 * Fortran I/O request modes 00254 */ 00255 00256 #define PARTIAL 0 /* Partial record I/O */ 00257 #define FULL 1 /* Full record I/O */ 00258 00259 /* 00260 * Codes for open processing 00261 */ 00262 00263 enum status_spec { OS_UNKNOWN = 1, OS_OLD, OS_NEW, OS_SCRATCH, 00264 OS_REPLACE }; 00265 #if defined(__mips) || defined(_LITTLE_ENDIAN) 00266 enum access_spec { OS_SEQUENTIAL = 1, OS_DIRECT, OS_OAPPEND, OS_KEYED }; 00267 #else 00268 enum access_spec { OS_SEQUENTIAL = 1, OS_DIRECT }; 00269 #endif 00270 enum form_spec { OS_FORMATTED = 1, OS_UNFORMATTED, OS_BINARY, OS_SYSTEM }; 00271 enum blank_spec { OS_NULL = 1, OS_ZERO }; 00272 enum position_spec { OS_REWIND = 1, OS_ASIS, OS_APPEND }; 00273 enum action_spec { OS_ACTION_UNSPECIFIED = 0, OS_READ = 1, OS_WRITE = 2, 00274 OS_READWRITE = (OS_READ | OS_WRITE) }; 00275 enum delim_spec { OS_NONE = 1, OS_QUOTE, OS_APOSTROPHE }; 00276 enum pad_spec { OS_NO = 1, OS_YES }; 00277 00278 /* 00279 * Codes for close processing 00280 */ 00281 00282 #define CLST_UNSPEC 0 /* STATUS= unspecified */ 00283 #define CLST_KEEP 1 /* STATUS='KEEP' */ 00284 #define CLST_DELETE 2 /* STATUS='DELETE' */ 00285 00286 /************************************************************************ 00287 * 00288 * Constants assigned to unit table fields. 00289 * 00290 ***********************************************************************/ 00291 /* 00292 * The following flags in 'uflag' are used within a READ/WRITE statement 00293 * and are cleared at finalization. 00294 */ 00295 00296 #define _UERRF 01 /* ERR= specified */ 00297 #define _UEORF 02 /* EOR= specified */ 00298 #define _UENDF 04 /* END= specified */ 00299 #define _UIOSTF 010 /* IOSTAT= specified */ 00300 00301 #define _UERRC 020 /* ERR condition */ 00302 #define _UEORC 040 /* EOR condition with ADVANCE='NO' */ 00303 #define _UENDC 0100 /* ENDFILE condition */ 00304 00305 /************************************************************************ 00306 * 00307 * The CVOLATILE macro must be defined to expand to "volatile" on 00308 * architectures like CRAY TS which support threading and where storing to 00309 * memory might render another processor's cache invalid. 00310 * 00311 * On other cache-coherent architectures like Sparc we expand CVOLATILE to 00312 * "volatile" for conceptual correctness, and because there is no negative 00313 * performance impact. 00314 * 00315 * CVOLATILE is not expanded to "volatile" on T3D systems because no 00316 * threading is supported and there would be a negative performance impact. 00317 * 00318 * 00319 * This keyword must be added to any globally accessed field or variable which 00320 * might be loaded prior to obtaining a lock (lock routines always render 00321 * the cache coherent) and the field or dataword is not read-only. This 00322 * comes up for locked data areas which are dynamically allocated on the 00323 * heap and are then initialized once and read-only from thence onward. The 00324 * fact that the data item previously was in the heap means that some processor 00325 * might have previously used the data area and then deallocated it with 00326 * free(3). That processor might have a stale data cache entry assigned 00327 * to the data word. 00328 * 00329 ***********************************************************************/ 00330 00331 #ifndef _CRAYT3D 00332 00333 #define CVOLATILE volatile 00334 00335 #else 00336 00337 #define CVOLATILE 00338 00339 #endif 00340 00341 /************************************************************************ 00342 * 00343 * Structure and Typedef Definitions 00344 * 00345 ***********************************************************************/ 00346 00347 typedef short s_flag; 00348 typedef long ftnlen; 00349 typedef _f_comp8 _gen_complex; /* Complex of largest supported kind */ 00350 00351 /* FP is a union which may contain a variety of pointer types */ 00352 00353 typedef union { 00354 FILE *std; 00355 struct fdinfo *fdc; 00356 } FP; 00357 00358 /* 00359 * Define the basic, or smallest, container for a noncharacter datum. 00360 */ 00361 00362 #if defined(__mips) || defined(_LITTLE_ENDIAN) 00363 typedef _f_int1 bcont; /* basic container is a half word */ 00364 #elif !defined(_WORD32) && (defined(_F_INT4) || defined(_F_REAL4)) 00365 typedef short bcont; /* basic container is a half word */ 00366 #else 00367 typedef long bcont; /* basic container is a word */ 00368 #endif 00369 00370 /* 00371 * Fortran unit structure 00372 * 00373 * UNIT_HEADER is the offset to the start of the part of the unit table 00374 * which is initialized by _init_unit(). 00375 */ 00376 00377 #define UNIT_HEADER (offsetof(unit, auxlockp)) 00378 00379 typedef struct unit_s { 00380 00381 /****************************************************************************** 00382 * * 00383 * Hash Table Fields Section * 00384 * * 00385 * Fields used to manage the hash table of units. * 00386 * * 00387 * Fields in this section must be at the start of the structure. * 00388 * This is to help _init_unit() efficiently initialize all the other * 00389 * fields. All these fields (except uiolock) must never be reset * 00390 * because they are needed to maintain a coherent hash table of units. * 00391 * * 00392 * The CVOLATILE keyword is added to hashlink, uid, private, and utid * 00393 * because these fields are loaded by _get_cup() prior to entering a * 00394 * critical region. * 00395 * * 00396 ******************************************************************************/ 00397 00398 struct unit_s * CVOLATILE hashlink; /* Next unit in hash chain */ 00399 CVOLATILE unum_t uid; /* Unit number, -1 if internal*/ 00400 /* unit */ 00401 CVOLATILE int private; /* 1 if private, 0 if global */ 00402 CVOLATILE int utid; /* Tskid of owner of priv unit*/ 00403 plock_t uiolock; /* Unit lock */ 00404 00405 /****************************************************************************** 00406 * * 00407 * Connection Properties Section * 00408 * * 00409 * Fields describing unchanging properties of the connection. * 00410 * * 00411 ******************************************************************************/ 00412 00413 plock_t *auxlockp; /* Pointer to optional 2nd lock (stdio) */ 00414 int ufs; /* Describes the I/O processing method */ 00415 char *ufnm; /* File name or alias */ 00416 ino_t uinode; /* Unique file inode identifier */ 00417 dev_t udevice; /* Unique file device number */ 00418 char *alfnm; /* Actual file name */ 00419 long urecl; /* RECL value; 0 if absent on sequential*/ 00420 int usysfd; /* File descriptor. A value of -1 */ 00421 /* usually indicates no 'normal' file */ 00422 /* is associated with the unit. */ 00423 long uflagword; /* Returned flag word from FC_GETINFO */ 00424 int ucharset; /* Foreign character set */ 00425 int unumcvrt; /* Foreign numeric conversion */ 00426 int ualignmask; /* 0 or __fndc_align[cup->unumcvrt]->gran - 1*/ 00427 struct _dal_s ualign; /* FDC alignment information */ 00428 00429 unsigned 00430 uostatus:3, /* STATUS value (enum status_specifier) */ 00431 uposition:3, /* POSITION value (enum position_specifier) */ 00432 uaction :3, /* ACTION value (enum action_specifier) */ 00433 udelim :3, /* DELIM value (enum delim_spec) */ 00434 upad :3, /* PAD value (enum pad_specifier) */ 00435 utrunc :1, /* 1 if trunc. after sequential write */ 00436 ubmx :1, /* 1 if -s bmx selected by user */ 00437 usysread:1, /* 1 if file has system read permission */ 00438 usyswrite:1, /* 1 if file has system write permission*/ 00439 useek :1, /* 1 if backspace or use direct access */ 00440 ublkd :1, /* 1 if record blocking is present */ 00441 ublnk :1, /* 1 if BLANK='ZERO' on open */ 00442 ufmt :1, /* 1 if FORM='FORMATTED' */ 00443 useq :1, /* 1 if ACCESS='SEQUENTIAL' */ 00444 uscrtch :1, /* 1 if file is a scratch or temp file */ 00445 unlinked:1, /* 1 if file has been unlinked */ 00446 usnglink:1, /* 1 if file is not a linked file */ 00447 umultfil:1, /* 1 if multiple endfile records allowed*/ 00448 uft90 :1, /* 0/1 if Fortran 77/90 compatible */ 00449 umultup :1, /* 1 if -m on permits multiple access */ 00450 utmpfil :1, /* 1 if assigned with -t */ 00451 ok_wr_seq_fmt:1,/* 1 if seq fmt write is supported */ 00452 ok_wr_seq_unf:1,/* 1 if seq unfmted write is supported */ 00453 ok_wr_dir_fmt:1,/* 1 if dir fmt write is supported */ 00454 ok_wr_dir_unf:1,/* 1 if dir unfmted write is supported */ 00455 ok_rd_seq_fmt:1,/* 1 if seq fmt read is supported */ 00456 ok_rd_seq_unf:1,/* 1 if seq unfmted read is supported */ 00457 ok_rd_dir_fmt:1,/* 1 if dir fmt read is supported */ 00458 ok_rd_dir_unf:1,/* 1 if dir unfmted read is supported */ 00459 ufcompat:3, /* 0/1/2/3 if cf77/cf90/irxf77/irxf90 compat */ 00460 ufcomsep:1, /* 1 no comma-separated list-dir output */ 00461 ufunilist:1, /* 1 if not unicos list-dir output */ 00462 ufcomplen:1, /* 1 if compressed leng list-dir output */ 00463 ufrptcnt:1, /* 1 no repeat count in list-dir output */ 00464 ufnl_skip:1, /* 1 if skipping mismatched nl grp name */ 00465 ufnegzero:1, /* 1 if skip minus sign in fmt write of -0.0 */ 00466 ukeyed :1, /* 1 if ACCESS='KEYED' */ 00467 ubinary :1, /* 1 if FORM='BINARY' */ 00468 usystem :1; /* 1 if FORM='SYSTEM' */ 00469 00470 /****************************************************************************** 00471 * * 00472 * Unit State Section * 00473 * * 00474 * Fields which contain state information which must be remembered * 00475 * from one I/O statement to the next. * 00476 * * 00477 ******************************************************************************/ 00478 00479 FP ufp; /* Low-level file pointer */ 00480 00481 struct repdata *urepdata;/* Repdata structure for list read */ 00482 00483 int upfcstsz; /* Size of parsed format count stack */ 00484 int *upfcstk; /* Pointer to parsed format count stack */ 00485 00486 unsigned 00487 unitchk :1, /* 1 if UNIT was called since last BUFFER I/O */ 00488 urecmode:1, /* FULL or PARTIAL record mode for buffer I/O */ 00489 uerr :1, /* 1 if error on last buffer in/out */ 00490 uwrt :1, /* 1 if last io was write */ 00491 pnonadv :1, /* 1 if ADVANCE='NO' on prev I/O */ 00492 uspcproc:1; /* 1 if in EOV special processing (tapes) */ 00493 00494 /* 00495 * The uend field is used to track a file's position relative to 00496 * a final endfile record. A 'logical endfile' record exists at 00497 * the end of any sequential file which does not have a physical 00498 * endfile preceding the EOD. 00499 */ 00500 00501 enum { 00502 BEFORE_ENDFILE = 0, 00503 PHYSICAL_ENDFILE = 1, 00504 LOGICAL_ENDFILE = 2 00505 } uend :3; /* 0 if not positioned past a final * 00506 * endfile record. PHYSICAL_ENDFILE if * 00507 * positioned after a logical endfile * 00508 * record. LOGICAL_ENDFILE if * 00509 * positioned after a logical endfile * 00510 * record. */ 00511 00512 long uwaddr; /* Current word address for -s bin */ 00513 00514 int64 ulrecl; /* Length in bits of previous BUFFER IN,* 00515 * BUFFER OUT, READ, or WRITE. Used for* 00516 * the LENGTH function. */ 00517 enum { 00518 ASYNC_NOTOK = 0, 00519 ASYNC_OK = 1, 00520 ASYNC_ACTIVE = 2 00521 } uasync; /* > 0 if async permitted or active */ 00522 00523 struct ffsw uffsw; /* Status word for asynchronous I/O */ 00524 00525 union stat_ntry *ftstat;/* Pointer to Fortran statistics packet */ 00526 00527 long ufbitpos; /* Bit position in file for PURE files */ 00528 00529 /* Direct access */ 00530 00531 recn_t udamax; /* Largest record number on file */ 00532 recn_t udalast; /* Last record number read or written */ 00533 00534 /* Formatted, list-directed, or namelist I/O */ 00535 00536 /****************************************************************************** 00537 * Line buffer conventions (disregard at your own peril): * 00538 * * 00539 * ulinebuf Set in OPEN/CLOSE processing and--possibly--during * 00540 * I/O statement initialization. * 00541 * * 00542 * ulineptr Pointer to current position in line buffer. * 00543 * * 00544 * uflshptr Pointer to unflushed part of line buffer. This is * 00545 * used only for sequential writes. * 00546 * * 00547 * ulinecnt On output (writing), this is the offset or current * 00548 * position in the line buffer; note that ulineptr is * 00549 * normally defined as &ulinebuf[ulinecnt]. On input * 00550 * (reading), this is the number of characters left in * 00551 * the line buffer. * 00552 * * 00553 * ulinemax On output (writing), this is the highwater mark in * 00554 * the line buffer (e.g., on a tab-left operation, * 00555 * ulineptr and ulinecnt are updated but ulinemax is * 00556 * unchanged). Note that for output paths that do not * 00557 * support tabbing (list-directed output, for example), * 00558 * ulinemax is used in lieu of ulinecnt, and ulinecnt * 00559 * is undefined. This field is never used on input * 00560 * (reading). * 00561 * * 00562 * urecsize Minimum physical size of line buffer and record size * 00563 * (RECL) of current record. ulinemax must NEVER be * 00564 * larger than this value; ulinecnt may exceed it after * 00565 * a tab-right operation. * 00566 * * 00567 * uldwsize Analogue of urecsize for list-directed writes only. * 00568 * * 00569 * unmlsize Analogue of urecsize for namelist writes only. * 00570 * * 00571 ******************************************************************************/ 00572 00573 long *ulinebuf; /* Unpacked line buffer */ 00574 long *ulineptr; /* Current position in line buffer */ 00575 long *uflshptr; /* Unflushed part of line buffer */ 00576 long ulinemax; /* Max position in line buffer to write */ 00577 long ulinecnt; /* Character count in line buffer */ 00578 long urecsize; /* Length of line buffer (characters) */ 00579 long uldwsize; /* Length for list-directed writes */ 00580 long unmlsize; /* Length for namelist writes */ 00581 00582 /****************************************************************************** 00583 * * 00584 * Statement State Section * 00585 * * 00586 * Fields which contain the state of the current I/O statement. * 00587 * * 00588 ******************************************************************************/ 00589 00590 _f_int *uiostat; /* IOSTAT parameter address for cf77 */ 00591 long uflag; /* Flag word used by interface routines */ 00592 unsigned 00593 ueor_found:1, /* Found eor already on read */ 00594 f_lastwritten:1; /* 1 if we already terminated */ 00595 /* the record */ 00596 /* Only those routines that care about */ 00597 /* lastiolist currently look at this */ 00598 void *f_lastiolist; /* Set in some of the compiler-library */ 00599 /* interface routines. If */ 00600 /* iolist_header->iollast is set, this */ 00601 /* can be set to the address of the end */ 00602 /* of the iolist; otherwise NULL. */ 00603 00604 /* Unformatted I/O */ 00605 00606 int64 urecpos; /* Bit position in current record */ 00607 int ulastyp; /* Type of previous I/O list item */ 00608 00609 } unit; 00610 00611 /* 00612 * Fortran unit hash table structure. A hash table consists of an 00613 * array of these structures. The units in each hash chain are 00614 * linked together via the "hashlink" field in the unit table. 00615 * 00616 */ 00617 typedef CVOLATILE struct { 00618 unit *ulist; /* Unit at head of hash chain */ 00619 } unit_htable; 00620 00621 /* 00622 * The per-task I/O statement state structure 00623 */ 00624 00625 struct fiostate { 00626 unit *f_cu; /* Current unit */ 00627 long f_iostmt; /* Current I/O statement type */ 00628 unum_t f_curun; /* Current unit number */ 00629 s_flag f_intflg; /* 1 if internal file */ 00630 long f_rtbgn; /* RT value at start of I/O statement */ 00631 unsigned f_shrdput:1; /* 1 if we need to do a shmem_wait_put */ 00632 /* Should be set only on MPP systems */ 00633 00634 union iostate { 00635 /* 00636 * Unformatted I/O 00637 */ 00638 struct unfstate { 00639 int recpos; /* Bit position in current record */ 00640 int lastyp; /* Type of previous I/O list item */ 00641 } unf; 00642 00643 /* 00644 * Formatted/list-directed I/O 00645 */ 00646 struct fmtstate { 00647 int (*endrec)( 00648 struct fiostate *css, 00649 unit *cup, 00650 int count); 00651 /* Record processing function */ 00652 00653 long *leftablim; /* Left tab limit for current statement */ 00654 char *icp; /* Internal I/O character pointer */ 00655 char *tempicp; /* Ptr to a free-able copy of internal file */ 00656 int icl; /* Internal I/O character length */ 00657 int iiae; /* Number of internal array elements */ 00658 /* Negative if pre-5.0 code */ 00659 /* Zero or greater if 5.0 code or later */ 00660 00661 unsigned 00662 freefmtbuf:1, /* 1 if temporary unparsed format to be freed */ 00663 freepfmt:1, /* 1 if parsed format to be freed */ 00664 lcomma :1, /* List-directed read comma flag */ 00665 blank0 :1, /* 1 if blanks currently treated as nulls */ 00666 cplus :1, /* 1 if + sign is printed for pos numbers */ 00667 nonl :1, /* 1 if no new line, 0 if newline */ 00668 nonadv :1, /* 1 if ADVANCE='NO' */ 00669 slash :1; /* 1 if list input encountered a slash */ 00670 00671 union { 00672 00673 struct { 00674 char *fmtbuf; /* Pointer to unparsed (ASCII) format */ 00675 int fmtcol; /* Current position in unparsed format*/ 00676 int fmtlen; /* Length of unparsed format */ 00677 int fmtnum; /* Fortran statement label of format */ 00678 fmt_type *pfmt; /* Pointer to parsed format */ 00679 fmt_type *pfcp; /* Parsed format current position */ 00680 int *pftocs; /* Current top of count stack */ 00681 00682 int charcnt; /* Character count for SIZE on read */ 00683 long scale; /* Current scale factor */ 00684 } fe; /* formatted editing */ 00685 00686 /* 00687 * The "le" structure contains state of the current list-directed 00688 * output statement. repcnt, value/copy, elsize, and type all 00689 * are used to save the last output value processed. We 00690 * defer printing of output items until we know that we have 00691 * no more opportunity to combine consecutive equivalent values 00692 * into one value with a repeat count. 00693 * 00694 * The ndchar bit is set if the last *printed* value was 00695 * non-delimited character. This must be remembered because it 00696 * affects the choice of value separator used. 00697 */ 00698 struct { 00699 union { 00700 long value[4]; /* Repeated output value */ 00701 void *copy; /* Pointer to copy of output value */ 00702 } u; 00703 int repcnt; /* Number of repeated output values */ 00704 int elsize; /* Byte size of repeated value */ 00705 ftype_t type :8; /* Data type of repeated value */ 00706 unsigned ndchar :1; /* 1 if prev type was nondelim char */ 00707 unsigned item1 :1; /* 1 if first item in I/O list */ 00708 unsigned ldwinit :1; /* 1 if first call to _ld_write */ 00709 } le; /* list-directed editing */ 00710 00711 } u; 00712 00713 } fmt; 00714 } u; 00715 }; 00716 00717 /* FIOSPTR - synonym for (struct fiostate *) */ 00718 00719 typedef struct fiostate *FIOSPTR; 00720 00721 /* olist - for open processing */ 00722 00723 typedef struct { 00724 s_flag oerr; 00725 _f_int ounit; 00726 char *ofile; 00727 ftnlen ofilelen; 00728 enum status_spec ostatus; 00729 enum access_spec oaccess; 00730 enum form_spec oform; 00731 _f_int orecl; 00732 enum blank_spec oblank; 00733 enum position_spec oposition; 00734 enum action_spec oaction; 00735 enum delim_spec odelim; 00736 enum pad_spec opad; 00737 } olist; 00738 00739 /* cllist - for close processing */ 00740 00741 typedef struct { 00742 s_flag cerr; 00743 _f_int cunit; 00744 char *csta; 00745 } cllist; 00746 00747 /* inlist - for INQUIRE processing */ 00748 00749 typedef struct { 00750 s_flag inerr; 00751 _f_int inunit; 00752 char *infile; 00753 ftnlen infilen; 00754 _f_log *inex; /* parameters in standard's order */ 00755 _f_log *inopen; 00756 _f_int *innum; 00757 _f_log *innamed; 00758 char *inname; 00759 ftnlen innamlen; 00760 char *inacc; 00761 ftnlen inacclen; 00762 char *inseq; 00763 ftnlen inseqlen; 00764 char *indir; 00765 ftnlen indirlen; 00766 char *infmt; 00767 ftnlen infmtlen; 00768 char *inform; 00769 _f_int informlen; 00770 char *inunf; 00771 ftnlen inunflen; 00772 _f_int *inrecl; 00773 _f_int *innrec; 00774 char *inblank; 00775 ftnlen inblanklen; 00776 char *inposit; /* POSITION specifier pointer */ 00777 ftnlen inpositlen; /* POSITION specifier length */ 00778 char *inaction; /* ACTION specifier pointer */ 00779 ftnlen inactonlen; /* ACTION specifier length */ 00780 char *inread; /* READ specifier pointer */ 00781 ftnlen inreadlen; /* READ specifier length */ 00782 char *inwrite; /* WRITE specifier pointer */ 00783 ftnlen inwritelen; /* WRITE specifier length */ 00784 char *inredwrit; /* READWRITE specifier pointer */ 00785 ftnlen inrdwrtlen; /* READWRITE specifier length */ 00786 char *indelim; /* DELIM specifier pointer */ 00787 ftnlen indelimlen; /* DELIM specifier length */ 00788 char *inpad; /* PAD specifier pointer */ 00789 ftnlen inpadlen; /* PAD specifier length */ 00790 } inlist; 00791 00792 /* 00793 * Type Information Packet 00794 * 00795 * This data structure is used extensively in the data-transfer I/O 00796 * calls. It exists to consolidate the data type information and to 00797 * reduce the number of parameters in the mid-level libf routines. 00798 * It also contains information relevant to numeric data conversion. 00799 * 00800 * N.B. type77 may not always be correct, especially when libf is 00801 * entered through one of the f90 interface routines; in which case 00802 * it will be set to -1. However, the mid- and low-level routines 00803 * should all be using the type90 field. 00804 */ 00805 00806 typedef struct type_information_packet { 00807 ftype_t type90; /* Fortran 90/95 data type */ 00808 short type77; /* Fortran 77 data type */ 00809 short intlen; /* Internal data length (bits) */ 00810 short extlen; /* External data length (bits) */ 00811 short cnvindx; /* Data conversion index */ 00812 long count; /* Number of data items */ 00813 long stride; /* Stride between data items */ 00814 00815 /* Element size is the internal length multiplied by the */ 00816 /* number of elements (equivalent to intlen for everything */ 00817 /* but CHARACTER data), though expressed in bytes. */ 00818 00819 long elsize; /* Element size (bytes) */ 00820 00821 /* The following fields are defined iff cnvindx != 0 */ 00822 00823 short newfunc; /* 1 if new-style conv. func. */ 00824 short cnvtype; /* Data conversion pseudo-type */ 00825 int (* cnvfunc)(); /* Data conversion function */ 00826 } type_packet; 00827 00828 /* 00829 * The xfer_func typedef is a prototype for any functions called by 00830 * _xfer_iolist. 00831 */ 00832 00833 typedef int xfer_func(FIOSPTR css, unit *cup, void *dptr, type_packet *tip, 00834 int mode); 00835 00836 /* 00837 * The xfer_func_c typedef is a prototype for functions which process 00838 * input or output of contiguous data. 00839 */ 00840 00841 typedef long xfer_func_c(unit *cup, void *uda, type_packet *tip, int mode, 00842 int *ubc_ret, long *wr, int *status); 00843 00844 /************************************************************************ 00845 * 00846 * Error Handling Macros 00847 * 00848 * RERROR (error_number); 00849 * RERROR1(error_number, parameter); 00850 * 00851 * These routines either terminate the program with an error, or if 00852 * the user is processing errors, returns the error number. Two 00853 * versions of each routine exist to allow for a parameter to be 00854 * substituted in the error message. 00855 * 00856 * RERROR and RERROR1 should be used once the unit table pointer has 00857 * been established. 00858 * 00859 * GOERROR and GOERROR1 are used where a jump-to-label is desired upon 00860 * reaching an error condition. They set a special variable (errn) to the 00861 * return value and jump to a label. 00862 * 00863 ***********************************************************************/ 00864 00865 00866 #define ABORT_ON_ERROR (cup == NULL || (cup->uflag & (_UERRF | _UIOSTF)) == 0) 00867 00868 #define RERROR(n) { \ 00869 if (ABORT_ON_ERROR) \ 00870 _ferr(css, n); \ 00871 else \ 00872 return(n); \ 00873 } 00874 00875 #define RERROR1(n, p) { \ 00876 if (ABORT_ON_ERROR) \ 00877 _ferr(css, n, p); \ 00878 else \ 00879 return(n); \ 00880 } 00881 00882 #define GOERROR(err, label) { errn = err; goto label; } 00883 #define GOERROR1(err, p, label) { errn = err; parm = p; goto label; } 00884 00885 /************************************************************************ 00886 * 00887 * EOF Handling Macro 00888 * 00889 * REND(error_number); 00890 * 00891 * REND either terminates the program with an EOF-type error, or if 00892 * the user is processing errors, returns the negative error number. 00893 * 00894 ***********************************************************************/ 00895 #define REND(n) { \ 00896 if ((cup == NULL) || (cup->uflag & (_UENDF | _UIOSTF)) == 0) \ 00897 _ferr(css, n); \ 00898 else \ 00899 return(n); \ 00900 } 00901 00902 /************************************************************************ 00903 * 00904 * Multitasking Macros 00905 * 00906 ***********************************************************************/ 00907 00908 #ifdef _UNICOS 00909 #define INITIALIZE_LOCK(x) { (x) = 0; } 00910 #elif defined(__mips) || (defined(_LITTLE_ENDIAN) && defined(__sv2)) 00911 #define INITIALIZE_LOCK(x) { (x) = 0; } 00912 #elif defined(_SOLARIS) 00913 #define INITIALIZE_LOCK(x) mutex_init(&(x), USYNC_THREAD, NULL) 00914 #elif defined(_LITTLE_ENDIAN) && !defined(__sv2) 00915 #define INITIALIZE_LOCK(x) { (x) = 0; } 00916 #endif 00917 00918 #define OPENLOCK() MEM_LOCK(&_openlock) 00919 00920 #define OPENUNLOCK() MEM_UNLOCK(&_openlock) 00921 00922 #define PARSELOCK() MEM_LOCK(&_parselock) 00923 00924 #define PARSEUNLOCK() MEM_UNLOCK(&_parselock) 00925 00926 /* 00927 * FLSH_MEM 00928 * Ensures that any prior stores complete before any following 00929 * stores. 00930 * 00931 * On PVP systems, the "suppress" ensures stores are issued and 00932 * the _cmr() Waits for this CPU's memory stores to complete. 00933 * 00934 * On Sparc systems, the call to the _flsh_mem routine ensures 00935 * that all prior stores are issued (not held in registers). 00936 * 00937 * On other systems, threading is not supported, so FLSH_MEM 00938 * may be a no-op. 00939 * 00940 */ 00941 00942 #ifdef _CRAY1 00943 #define FLSH_MEM() { _Pragma("suppress"); _cmr(); } 00944 #elif defined(_SOLARIS) 00945 #define FLSH_MEM() { _flsh_mem(); } 00946 #else 00947 #define FLSH_MEM() { } 00948 #endif 00949 00950 /************************************************************************ 00951 * 00952 * General Macros 00953 * 00954 ***********************************************************************/ 00955 00956 /* 00957 * MAX and MIN 00958 * Prevent compiler warnings by removing any definition added 00959 * previously by other header files. 00960 */ 00961 #undef MAX 00962 #define MAX(a,b) ((a) > (b) ? (a) : (b)) 00963 00964 #undef MIN 00965 #define MIN(a,b) ((a) < (b) ? (a) : (b)) 00966 00967 #define FF2FTNST(ffstat) _ffstat_cnvt[ffstat] 00968 00969 /* 00970 * WAITIO 00971 * Wait for any outstanding I/O to complete. If an error in 00972 * the completed asynchronous request is found, "error_handle" 00973 * is executed. 00974 */ 00975 #ifdef DEBUG 00976 #define AIOCHK(cup) { if (cup->ufs != FS_FDC) _ferr(NULL, FEINTUNK); } 00977 #else 00978 #define AIOCHK(cup) 00979 #endif 00980 00981 #define MAXRECALL 1000000 00982 00983 #define WAITIO(cup, error_handle) { \ 00984 /* \ 00985 * If uasync is ASYNC_ACTIVE, then the last operation was \ 00986 * asynchronous. If the FFSTAT is zero, it has not yet \ 00987 * completed. \ 00988 */ \ 00989 if (cup->uasync == ASYNC_ACTIVE) { \ 00990 register int ct = 0; \ 00991 struct ffsw zzstat; \ 00992 struct fdinfo *llfio; \ 00993 \ 00994 llfio = (struct fdinfo *)cup->ufp.fdc; \ 00995 AIOCHK(cup); /* Do some DEBUG checking */ \ 00996 /* \ 00997 * If I/O is still busy, go into recall until the \ 00998 * request has been completed. If FFSTAT is != 0, \ 00999 * then we really called a synchronous routine, \ 01000 * and need not call the recall routine at all. \ 01001 */ \ 01002 while (FFSTAT(cup->uffsw) == 0) { \ 01003 (void)XRCALL(llfio, fcntlrtn) llfio, \ 01004 FC_RECALL, &cup->uffsw, &zzstat);\ 01005 \ 01006 if (ct++ > MAXRECALL) _ferr(NULL, FEINTUNK);\ 01007 } \ 01008 /* \ 01009 * Set ulrecl \ 01010 */ \ 01011 cup->ulrecl = (uint64)cup->uffsw.sw_count << 3; \ 01012 cup->ufbitpos += cup->ulrecl; /* for PURE */ \ 01013 if (cup->urecmode == PARTIAL) \ 01014 cup->urecpos += cup->ulrecl; \ 01015 \ 01016 switch (FFSTAT(cup->uffsw)) { \ 01017 case FFEOR: \ 01018 cup->ulastyp = DT_NONE; \ 01019 cup->urecpos = 0; \ 01020 case FFCNT: /* fall through ! */ \ 01021 cup->uend = BEFORE_ENDFILE; \ 01022 break; \ 01023 case FFEOF: \ 01024 cup->uend = PHYSICAL_ENDFILE; \ 01025 break; \ 01026 case FFEOD: \ 01027 if (cup->uend == BEFORE_ENDFILE) \ 01028 cup->uend = LOGICAL_ENDFILE;\ 01029 break; \ 01030 } \ 01031 \ 01032 cup->uasync = ASYNC_OK; \ 01033 /* \ 01034 * If error, perform requested action. \ 01035 */ \ 01036 if (cup->uffsw.sw_error != 0) { \ 01037 error_handle; \ 01038 } \ 01039 } \ 01040 } 01041 01042 /* 01043 * POWER_OF_TWO Define a macro to determine if an integer is a power of 01044 * two. Use the _popcnt() intrinsic on CRAY PVP sytems. 01045 */ 01046 01047 #ifdef _CRAY1 01048 #define POWER_OF_TWO(n) (_popcnt(n) == 1) 01049 #else 01050 #define POWER_OF_TWO(n) ((n & (n - 1)) == 0 && n != 0) 01051 #endif 01052 01053 /* 01054 * COMPADD Compute padding requirements for a particular file structure 01055 * and data conversion type. 01056 * 01057 * Parameters: 01058 * 01059 * unit *cup - (input) unit pointer 01060 * int pbytes - (output) number of pad bytes needed 01061 * int pbits - (output) number of pad bits to subtract from 01062 * pbytes 01063 * int pval - (output) the data area written out to 01064 * the file to fill the pad space. 01065 * 01066 */ 01067 01068 #if NUMERIC_DATA_CONVERSION_ENABLED 01069 #define COMPADD(cup, pbytes, pbits, pval) { \ 01070 register int64 bitpos, bits, gran; \ 01071 \ 01072 if (cup->ualign.pflag) { /* If aligning */ \ 01073 bitpos = cup->urecpos; \ 01074 gran = cup->ualign.gran; \ 01075 /* \ 01076 * Use bit masks rather than (slow) mod function if granularity is \ 01077 * a power of two. \ 01078 */ \ 01079 if (POWER_OF_TWO(gran)) { \ 01080 bits = gran - (bitpos & (gran - 1)); \ 01081 bits &= gran - 1; \ 01082 } \ 01083 else { \ 01084 bits = gran - (bitpos % gran); \ 01085 bits = bits % gran; \ 01086 } \ 01087 pbytes = (bits + 7) >> 3; \ 01088 pbits = (pbytes << 3) - bits; \ 01089 pval = cup->ualign.padval; \ 01090 } \ 01091 else /* No aligning */ \ 01092 pbytes = pbits = pval = 0; \ 01093 } 01094 #else 01095 #define COMPADD(cup, pbytes, pbits, pval) pbytes = pbits = pval = 0; 01096 #endif /* NUMERIC_DATA_CONVERSION_ENABLED */ 01097 01098 /* 01099 * SET_F90_INFO Construct a pseudo-f90/f95 type descriptor and type 01100 * information packet for f77 entry points. 01101 * 01102 * Parameters: 01103 * 01104 * struct f90_type ts f90/f95 type descriptor (output) 01105 * type_packet tip Type information packet (output) 01106 * short type77 Fortran 77 data type (input) 01107 * 01108 */ 01109 01110 #define CREATE_F90_INFO(ts, tip, type77) { \ 01111 ts.type = _f77_to_f90_type_cnvt[type77]; \ 01112 ts.dpflag = (type77 == DT_DBLE) ? 1 : 0; \ 01113 ts.int_len = _f77_type_len[type77] << 3; \ 01114 ts.dec_len = ts.int_len >> 3; \ 01115 if (type77 == DT_SINT) { \ 01116 ts.kind_or_star = DVD_STAR; \ 01117 if (ts.dec_len == sizeof(_f_int)) \ 01118 ts.dec_len = ts.dec_len >> 1; \ 01119 } \ 01120 else \ 01121 ts.kind_or_star = DVD_DEFAULT; \ 01122 tip.type77 = type77; \ 01123 tip.type90 = ts.type; \ 01124 tip.intlen = ts.int_len; \ 01125 tip.extlen = ts.int_len; \ 01126 tip.elsize = ts.int_len >> 3; \ 01127 tip.stride = 1; \ 01128 tip.cnvindx = 0; \ 01129 } 01130 01131 /* 01132 * GOOD_UNUM(u) - verifies unit numbers. Returns 1 if the given 01133 * unit number could be connected. 01134 */ 01135 01136 #define GOOD_UNUM(u) ((u) >= 0) 01137 01138 /* 01139 * RSVD_UNUM(u) - returns 1 iff u is a reserved unit number which cannot 01140 * be opened by the user. 01141 */ 01142 01143 #define RSVD_UNUM(_U) ((_U) >= STDIN_U && (_U) <= STDERR_U) 01144 01145 /* 01146 * OPEN_UPTR - returns 1 iff u points to a connected unit. Returns 0 01147 * if u is unconnected. 01148 */ 01149 01150 #define OPEN_UPTR(_U) ((_U) != NULL && (_U)->ufs != 0) 01151 01152 /* 01153 * UHASH - computes the hash value for a unit number = x mod HASH_SIZE 01154 */ 01155 01156 #define UHASH(x) (x & (HASH_SIZE - 1)) 01157 01158 /* 01159 * UNIT_NUM and GT_UNUM get the unit number for a given unit pointer. 01160 */ 01161 01162 #define UNIT_NUM(_U) ((_U)->uid) 01163 01164 #define GT_UNUM(_U, _N) { _N = UNIT_NUM(_U); } 01165 01166 /* 01167 * MYTASK expands to a unique task identification number. 01168 */ 01169 01170 #ifdef _CRAY1 01171 #define MYTASK (t_tid()) 01172 #elif defined(_CRAYMPP) 01173 #define MYTASK (_my_pe()) 01174 #else 01175 #define MYTASK 0 01176 #endif 01177 01178 /* 01179 * STMT_BEGIN 01180 * 01181 * This macro stores information about the current I/O statement, 01182 * and snaps the current RT clock value for statistics gathering. 01183 * 01184 * Returned is a (locked) current unit pointer if the unit is connected. 01185 * Null is returned if the unit number is invalid or not connected. 01186 * 01187 * Arguments 01188 * 01189 * unum_t _UNUM - (input) unit number 01190 * int _INTFLAG - (input) 1 if internal file 01191 * int _STMTCODE - (input) statement code 01192 * long *_CILIST - (unused) cilist from Fortran 90 01193 * FIOSPTR _LOCFIOSP - (input) FIOSPTR from Fortran 90 01194 * or passed in from caller. If this 01195 * argument is NULL, task common 01196 * is used. 01197 * unit *_CUP - (output) unit pointer 01198 */ 01199 #ifndef _UNICOS 01200 #define _rtc() 0 01201 #endif 01202 #ifdef _CRAYMPP 01203 /* These macros are used for STOP_ALL processing */ 01204 #define INCRINIO {_infio++;} 01205 #define CHKSTOP { \ 01206 _infio--; \ 01207 if (_needtostop){ \ 01208 _f_stopsig(SIGBUFIO); \ 01209 } \ 01210 } 01211 #else 01212 #define INCRINIO 01213 #define CHKSTOP 01214 #endif 01215 #define STMT_BEGIN(_UNUM, _INTFLAG, _STMTCODE, _CILIST, _LOCFIOSP, _CUP) {\ 01216 FIOSPTR fiosp; \ 01217 \ 01218 assert( _CILIST == NULL ); \ 01219 if (_LOCFIOSP != NULL) \ 01220 fiosp = _LOCFIOSP; \ 01221 else \ 01222 GET_FIOS_PTR(fiosp); \ 01223 if (_INTFLAG) \ 01224 _CUP = _get_int_cup(); /* internal file */ \ 01225 else \ 01226 _CUP = _get_cup(_UNUM); /* external file */ \ 01227 \ 01228 /* Set fields which are accessed by _fcontext(). */ \ 01229 \ 01230 INCRINIO; \ 01231 fiosp->f_cu = _CUP; \ 01232 fiosp->f_curun = _UNUM; \ 01233 fiosp->f_intflg = _INTFLAG; \ 01234 fiosp->f_iostmt = _STMTCODE; \ 01235 \ 01236 if ((_STMTCODE) & TF_FMT) \ 01237 fiosp->u.fmt.u.fe.fmtbuf = NULL; \ 01238 \ 01239 fiosp->f_rtbgn = _rtc(); /* for statistics */ \ 01240 } 01241 01242 /* 01243 * STMT_END 01244 * 01245 * This macro processes the end of an I/O statement. The unit is 01246 * unlocked and procstat statistics are optionally posted if _CUP 01247 * is non-null. 01248 * 01249 * 01250 * Parameters 01251 * 01252 * unit *_CUP - (input) unit pointer 01253 * int _STATSCODE - (input) statement code or TF_WRITE 01254 * or TF_READ for statistics gathering 01255 * long *_CILIST - (unused) cilist from Fortran 90 01256 * FIOSPTR _LOCFIOSP - (input) FIOSPTR from Fortran 90 01257 * or passed in from caller. If this 01258 * argument is NULL, task common 01259 * is used. 01260 */ 01261 #define STMT_END(_CUP, _STATSCODE, _CILIST, _LOCFIOSP) { \ 01262 FIOSPTR fiosp; \ 01263 \ 01264 assert( _CILIST == NULL ); \ 01265 if (_LOCFIOSP != NULL) \ 01266 fiosp = _LOCFIOSP; \ 01267 else \ 01268 GET_FIOS_PTR(fiosp); \ 01269 if ((_CUP) != NULL) { \ 01270 if (fiosp->f_iostmt & TF_POS) \ 01271 cup->uposition = 0; \ 01272 FSTATS_POST(_CUP, _STATSCODE, fiosp); \ 01273 _release_cup(_CUP); /* unlock the unit */ \ 01274 } \ 01275 CHKSTOP \ 01276 fiosp->f_curun = -1; \ 01277 fiosp->f_iostmt = 0; \ 01278 fiosp->f_cu = NULL; \ 01279 } 01280 01281 /* 01282 * CFT77_RETVAL 01283 * 01284 * This macro returns the specified value to the CFT77 compiler- 01285 * generated code at the end of a library I/O interface routine. 01286 */ 01287 01288 #if defined(_CRAYMPP) || !defined(_UNICOS) 01289 #define CFT77_RETVAL(_VAL) (_VAL) 01290 #else /* _CRAYMPP || ! _UNICOS */ 01291 #define CFT77_RETVAL(_VAL) _sets3(_VAL) 01292 #endif 01293 01294 /* 01295 * GET_FIOS_PTR Assign a pointer to the Fortran I/O Statement 01296 * state structure in task common. 01297 */ 01298 01299 #define GET_FIOS_PTR(_P) _P = &_tsk_fiostate; 01300 01301 /* 01302 * IO_TYPE - macro to categorize a unit as to the type of Fortran I/O which 01303 * is permitted on it. 01304 * Returns FIO_SU, FIO_SF, FIO_DU, or FIO_DF. 01305 * 01306 * _U pointer to the unit table entry. 01307 */ 01308 01309 #define IO_TYPE(_U) ((_U->useq) ? \ 01310 (_U->ufmt ? FIO_SF : FIO_SU): \ 01311 (_U->ufmt ? FIO_DF : FIO_DU)) 01312 01313 /************************************************************************ 01314 * 01315 * External function prototypes 01316 * 01317 ***********************************************************************/ 01318 extern unit *_alloc_unit(unum_t unum, int private); 01319 extern void _fcleanup(void); 01320 extern void _fcontext(FIOSPTR fiosp); 01321 extern void _ferr(FIOSPTR fiosp, int _Errno, ...); 01322 extern long _frch(unit *_Cup, long *_Uda, long _Chars, int _Mode, 01323 long *_Status); 01324 extern long _fwch(unit *_Cup, long *_Uda, long _Chars, int _Mode); 01325 extern unit *_search_unit_list(unit *p, unum_t unum); 01326 extern unit *_get_next_unit(unit *p, int iflock, int iftask); 01327 extern unit *_implicit_open(int acc, int form, unum_t unum, int errf, 01328 int *errn); 01329 extern unit *_imp_open(struct fiostate *css, int acc, int form, unum_t unum, 01330 int errf, int *errn); 01331 extern unit *_imp_open77(struct fiostate *css, int acc, int form, 01332 unum_t unum, int errf, int *errn); 01333 extern void _initialize_fortran_io(void); 01334 extern void _init_unit(unit *cup); 01335 extern unit *_init_internal_unit(void); 01336 extern int _parse(FIOSPTR _Css, unit *_Cup, fmt_type **_Prsfmt); 01337 extern int _unit_bksp(unit *cup); 01338 extern int _unit_close(unit *cup, int cstat, FIOSPTR css); 01339 extern int _unit_scratch(unit *cup); 01340 extern int _unit_seek(unit *cup, recn_t recn, int iost); 01341 extern int _unit_trunc(unit *cup); 01342 extern int _setpos(FIOSPTR css, unit *cup, int *pa, int len); 01343 extern int _uniqinod(unit *cup, assign_info *aip); 01344 extern int _f_opn(char *actnam, unit *cup, FIOSPTR css, int tufs, 01345 int aifound, assign_info *aip, struct stat *statp, 01346 int statp_valid, int catcherr, int o_sysflgs); 01347 extern int _do_open(unit *cup, FIOSPTR css, int tufs, char *actnam, 01348 int flags, int aifound, assign_info *aip, 01349 union spec_u *fdspec, int catcherr); 01350 extern void _set_device_and_inode(int sysfd, dev_t *devicep, ino_t *inodep); 01351 01352 extern xfer_func _rdunf; 01353 extern xfer_func _wrunf; 01354 extern xfer_func _rdfmt; 01355 extern xfer_func _wrfmt; 01356 extern xfer_func _ld_read; 01357 extern xfer_func _ld_write; 01358 extern xfer_func_c _frwd; 01359 extern xfer_func_c _fwwd; 01360 01361 extern int _dw_endrec(FIOSPTR _Css, unit *_Cup, int _Count); 01362 extern int _iw_endrec(FIOSPTR _Css, unit *_Cup, int _Count); 01363 extern int _sw_endrec(FIOSPTR _Css, unit *_Cup, int _Count); 01364 extern int _nonadv_endrec(FIOSPTR _Css, unit *_Cup); 01365 extern int _lw_after_nonadv(FIOSPTR _Css, unit *_Cup, int _Linelimit, 01366 int _Namelistflag); 01367 01368 extern int _dr_endrec(FIOSPTR _Css, unit *_Cup, int _Count); 01369 extern int _ir_endrec(FIOSPTR _Css, unit *_Cup, int _Count); 01370 extern int _sr_endrec(FIOSPTR _Css, unit *_Cup, int _Count); 01371 01372 extern void _gather_data(void *lbuf, long items, long inc, int len, 01373 void *ptr); 01374 extern void _scatter_data (void *ptr, long items, long inc, int len, 01375 void *lbuf); 01376 01377 extern void _set_ok_flags(unit *cup); 01378 extern int _get_mismatch_error(int noabort, int iost, unit *cup, 01379 FIOSPTR css); 01380 01381 extern int _iochunk(FIOSPTR css, unit *cup, xfer_func *func, 01382 struct DvDimen *dimen, type_packet *tip, short nd, 01383 long extent, int bshft, bcont *addr); 01384 01385 extern void _flsh_mem(void); 01386 01387 extern int _deduce_fstruct(int, struct fdinfo *, int); 01388 extern void _setup_cvrt(unit *cup); 01389 extern void _b_char(char *a, char *b, ftnlen blen); 01390 extern void _copy_n_trim(char *a, ftnlen alen, char *b); 01391 /************************************************************************ 01392 * 01393 * External symbols 01394 * 01395 ***********************************************************************/ 01396 01397 #define errfile stderr 01398 01399 extern unit_htable _fort_unit[]; /* Hash table of units */ 01400 01401 extern plock_t _openlock; /* Connecting unit lock */ 01402 extern plock_t _ioblock; /* __iob table lock */ 01403 extern plock_t _parselock; /* Format parsing lock */ 01404 extern plock_t _stdin_lock; /* Stdin lock */ 01405 extern plock_t _stdout_lock; /* Stdout lock */ 01406 extern plock_t _stderr_lock; /* Stderr lock */ 01407 01408 extern int _f_rcsz; /* Default sequential formatted RECL */ 01409 extern int _f_ldsz; /* Default list-directed output RECL */ 01410 extern int _def_bin_bs; /* Default '-s bin' buffer size */ 01411 extern int _def_sbin_bs; /* Default '-s sbin' buffer size */ 01412 #ifdef _CRAYMPP 01413 extern volatile int _infio; /* Set when inside an i/o statement*/ 01414 extern volatile int _needtostop; /* Set when we need to stop */ 01415 #endif 01416 01417 /* External tables and structures (defined in tables.c) */ 01418 01419 extern const ftype_t 01420 _f77_to_f90_type_cnvt[DT_MAX]; /* f77 to f90 type conversion */ 01421 extern const short 01422 _f90_to_f77_type_cnvt[DVTYPE_NTYPES]; /* f90 to f77 type conv. */ 01423 extern const short 01424 _f77_type_len[DT_MAX]; /* f77 type lengths (bytes) */ 01425 extern const char * 01426 _f90_type_name[DVTYPE_NTYPES]; /* f90 data type names */ 01427 extern const char * 01428 _f77_type_name[DT_MAX]; /* f77 data type names */ 01429 extern const short 01430 _charset_cnvt[CS_MAX]; /* Character to numeric conv. */ 01431 extern const short 01432 _ffstat_cnvt[7]; /* FFIO to frch status conv. */ 01433 extern const short 01434 _old_namelist_to_f77_type_cnvt[10]; /* Namelist to f77 type cnv.*/ 01435 extern type_packet __tip_null; /* Null type packet */ 01436 01437 #ifdef _CRAY1 01438 #pragma _CRI taskcommon _tsk_fiostate 01439 #endif 01440 extern struct fiostate _tsk_fiostate; /* Task local I/O state */ 01441 extern short _fortran_io_is_init; /* 0 until Fortran I/O is init */ 01442 extern short _e_fortran_io_is_init; /* 0 until ext Fortran I/O is init */ 01443 extern short _i_fortran_io_is_init; /* 0 until int Fortran I/O is init */ 01444 extern unit *_fort_internal_unit; /* Pointer to internal unit */ 01445 01446 /************************************************************************ 01447 * 01448 * Inline Functions 01449 * 01450 ***********************************************************************/ 01451 01452 /* 01453 * _get_cup 01454 * 01455 * This inline function returns a unit pointer for a particular 01456 * unit connected to an external file. If the unit is not open, 01457 * then NULL is returned. The errstat parameter is assigned an 01458 * error status if an error is encountered. 01459 * 01460 * Any necessary locking of the unit is performed. 01461 * 01462 * NOTE: this version of _get_cup will be rewritten soon 01463 * when dynamic unit allocation is activated. 01464 * 01465 * Return value: 01466 * Pointer to a connected unit. If the unit number is not 01467 * connected NULL is returned. 01468 */ 01469 _PRAGMA_INLINE(_get_cup) 01470 static unit * 01471 _get_cup(unum_t unum) 01472 { 01473 unit *cup; 01474 01475 cup = _fort_unit[UHASH(unum)].ulist; 01476 01477 if (cup != NULL) { 01478 #ifdef _CRAYMPP 01479 if (cup->uid != unum) 01480 #else 01481 if (cup->private || cup->uid != unum) 01482 #endif 01483 cup = _search_unit_list(cup, unum); 01484 } 01485 01486 if (cup != NULL) { 01487 MEM_LOCK(&cup->uiolock); /* lock the unit */ 01488 if (OPEN_UPTR(cup)) { /* if unit is connected */ 01489 /* 01490 * Lock the auxiliary lock if this unit has one. 01491 * This lock is necessary for standard files, which 01492 * are connected to more than one unit. 01493 */ 01494 if (cup->auxlockp != NULL) { 01495 MEM_LOCK(cup->auxlockp); 01496 } 01497 } 01498 else { /* else unit is not connected */ 01499 MEM_UNLOCK(&cup->uiolock); 01500 cup = NULL; /* unit not connected */ 01501 } 01502 } 01503 return(cup); 01504 } 01505 01506 /* 01507 * _get_int_cup 01508 * 01509 * This inline function returns a unit pointer for an internal 01510 * file. 01511 * 01512 * Any necessary locking of the unit is performed. 01513 * 01514 * Return value: 01515 * Pointer to a unit. If an error occurs, then NULL is returned. 01516 */ 01517 01518 _PRAGMA_INLINE(_get_int_cup) 01519 static unit * 01520 _get_int_cup(void) 01521 { 01522 unit *cup; 01523 cup = _fort_internal_unit; 01524 if (cup == NULL) 01525 cup = _init_internal_unit(); 01526 MEM_LOCK(&cup->uiolock); 01527 return(cup); 01528 } 01529 01530 /* 01531 * _release_cup 01532 * 01533 * Unlock a unit pointer. 01534 */ 01535 _PRAGMA_INLINE(_release_cup) 01536 static void 01537 _release_cup(unit *cup) 01538 { 01539 MEM_UNLOCK(&cup->uiolock); 01540 if (cup->auxlockp != NULL) 01541 MEM_UNLOCK(cup->auxlockp); 01542 } 01543 01544 #if defined(LIBDEBUG) && ! defined(_UNICOS) 01545 /* 01546 * _ferr macro. This is handy on Sparc where tracebacks cannot be printed. 01547 */ 01548 #define _ferr \ 01549 fprintf(stderr,"ERROR on line %d in file \"%s\"\n", \ 01550 __LINE__, __FILE__), \ 01551 _ferr_routine 01552 #endif /* LIBDEBUG */ 01553 01554 #if defined(__mips) || defined(_LITTLE_ENDIAN) 01555 /* Putting the pragma inline before the function declaration wasn't */ 01556 /* effective on MIPS systems. */ 01557 #pragma inline _get_cup 01558 #pragma inline _get_int_cup 01559 #pragma inline _release_cup 01560 #endif 01561 01562 #endif /* !_FIO_H */