00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #pragma ident "@(#) libf/fio/rf.c 92.5 09/07/99 15:26:57"
00039
00040 #include <ctype.h>
00041 #include <errno.h>
00042 #include <liberrno.h>
00043 #include <fortran.h>
00044 #if defined(BUILD_OS_DARWIN)
00045 #include <stdlib.h>
00046 #else
00047 #include <malloc.h>
00048 #endif
00049 #include <stdlib.h>
00050 #include <string.h>
00051 #include <unistd.h>
00052 #include <cray/fmtconv.h>
00053 #include <cray/format.h>
00054 #include <cray/nassert.h>
00055 #ifndef _ABSOFT
00056 #include <sys/unistd.h>
00057 #endif
00058 #include "fio.h"
00059 #include "fmt.h"
00060 #include "fstats.h"
00061 #include "f90io.h"
00062 #ifdef _CRAYMPP
00063 #include <stdarg.h>
00064 #endif
00065
00066 #ifdef _UNICOS
00067
00068 #pragma _CRI duplicate $RFI as $RLI
00069 #pragma _CRI duplicate $RFA$ as $RLA$
00070 #pragma _CRI duplicate $RFA$ as $DFA$
00071 #pragma _CRI duplicate $RFF as $RLF
00072 #pragma _CRI duplicate $RFF as $DFF
00073
00074
00075 #define ARGS_6 (4 + 2*sizeof(_fcd)/sizeof(long))
00076 #define ARGS_7 (5 + 2*sizeof(_fcd)/sizeof(long))
00077 #define ARGS_8 (6 + 2*sizeof(_fcd)/sizeof(long))
00078 #define ARGS_9 (7 + 2*sizeof(_fcd)/sizeof(long))
00079
00080 #define ZERO ((int) '0')
00081
00082 int $RFF(void);
00083
00084 #define ERROR0(cond, n) { \
00085 if (!(cond)) \
00086 _ferr(css, (n)); \
00087 else \
00088 goto error; \
00089 }
00090
00091 #define ERROR1(cond, n, p) { \
00092 if (!(cond)) \
00093 _ferr(css, (n), p); \
00094 else \
00095 goto error; \
00096 }
00097
00098
00099
00100
00101 #define IS_PFORM_BROKEN (_numargs() < ARGS_9)
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 #ifdef _CRAYMPP
00134 int
00135 $RFI(
00136 _fcd funit,
00137 ...
00138 )
00139 #else
00140 int
00141 $RFI(
00142 _fcd funit,
00143 _fcd format,
00144 long *err,
00145 long *end,
00146 _f_int *iostat,
00147 _f_int *rec,
00148 fmt_type **pform,
00149 long *inumelt,
00150 long *inumcfe
00151 )
00152 #endif
00153 {
00154 register int endf;
00155 register int errf;
00156 register int errn;
00157 register int iost;
00158 register int iotp;
00159 register recn_t recn;
00160 register unum_t unum;
00161 fmt_type **prsfmt;
00162 unit *cup;
00163 FIOSPTR css;
00164 #ifdef _CRAYMPP
00165 va_list args;
00166 _fcd format;
00167 long *err;
00168 long *end;
00169 _f_int *iostat;
00170 _f_int *rec;
00171 fmt_type **pform;
00172 long *inumelt;
00173 long *inumcfe;
00174 #endif
00175
00176 GET_FIOS_PTR(css);
00177
00178
00179
00180 if (css->f_iostmt != 0)
00181 _ferr(css, FEIOACTV);
00182
00183 #ifdef _CRAYMPP
00184 va_start(args, funit);
00185 format = va_arg(args, _fcd);
00186 err = va_arg(args, long *);
00187 end = va_arg(args, long *);
00188 iostat = va_arg(args, _f_int *);
00189 rec = va_arg(args, _f_int *);
00190 if (_numargs() > ARGS_6) {
00191 pform = va_arg(args, fmt_type **);
00192 if (_numargs() > ARGS_7) {
00193 inumelt = va_arg(args, long *);
00194 if (_numargs() > ARGS_8) {
00195 inumcfe = va_arg(args, long *);
00196 }
00197 }
00198 }
00199 va_end(args);
00200 #endif
00201 errn = 0;
00202
00203
00204
00205 if (iostat != NULL)
00206 *iostat = 0;
00207
00208 errf = ((err != NULL) || (iostat != NULL));
00209 endf = ((end != NULL) || (iostat != NULL));
00210
00211
00212
00213 iost = (_fcdtocp(format) != NULL) ? T_RSF : T_RLIST;
00214 iotp = SEQ;
00215
00216
00217
00218 if (_fcdlen(funit) > 0) {
00219 iotp = INT;
00220 STMT_BEGIN(-1, 1, iost, NULL, css, cup);
00221 }
00222 else {
00223 unum = **(_f_int **) &funit;
00224
00225 if (rec != NULL) {
00226 iost = T_RDF;
00227 iotp = DIR;
00228 recn = *rec;
00229 }
00230
00231 STMT_BEGIN(unum, 0, iost, NULL, css, cup);
00232
00233 if (cup == NULL) {
00234 int stat;
00235
00236 cup = _imp_open77(css, iotp, FMT, unum, errf, &stat);
00237
00238
00239
00240
00241
00242
00243 if (cup == NULL) {
00244 errn = stat;
00245 goto error;
00246 }
00247 }
00248 }
00249
00250
00251
00252 assert (cup != NULL);
00253
00254
00255
00256 cup->uflag = (err != NULL ? _UERRF : 0) |
00257 (end != NULL ? _UENDF : 0) |
00258 (iostat != NULL ? _UIOSTF : 0);
00259 cup->uiostat = iostat;
00260
00261 if (iotp != INT) {
00262
00263
00264
00265 if ((cup->uaction & OS_READ) == 0) {
00266 errn = FENOREAD;
00267 ERROR0(errf, errn);
00268 }
00269
00270
00271
00272 if (!cup->ufmt) {
00273 errn = FEFMTTIV;
00274 ERROR0(errf, errn);
00275 }
00276
00277
00278
00279 if (cup->useq && cup->uwrt != 0) {
00280 errn = FERDAFWR;
00281 ERROR0(errf, errn);
00282 }
00283 }
00284
00285
00286
00287 cup->uwrt = 0;
00288
00289
00290
00291 css->u.fmt.icp = NULL;
00292 css->u.fmt.blank0 = cup->ublnk;
00293 css->u.fmt.lcomma = 0;
00294 css->u.fmt.slash = 0;
00295 css->u.fmt.freepfmt = 0;
00296 #ifdef _CRAYMPP
00297 css->f_shrdput = 0;
00298 #endif
00299
00300 if (_fcdtocp(format) != NULL) {
00301 char *fptr;
00302 int flen;
00303 int fnum;
00304 int stsz;
00305
00306
00307
00308
00309 css->u.fmt.u.fe.fmtbuf = NULL;
00310 css->u.fmt.u.fe.fmtnum = 0;
00311 css->u.fmt.u.fe.fmtcol = 0;
00312 css->u.fmt.u.fe.scale = 0;
00313 css->u.fmt.u.fe.charcnt = 0;
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 if (_fcdlen(format) == 0) {
00338 fptr = *(char **) &format;
00339 flen = strlen(fptr);
00340 }
00341 else {
00342 register int repl;
00343
00344 if (_numargs() > ARGS_8 && inumcfe != NULL)
00345 repl = *inumcfe;
00346 else
00347 repl = -1;
00348
00349 fptr = _fcdtocp(format);
00350 flen = (repl >= 0) ? repl * _fcdlen(format) :
00351 strlen(fptr);
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361 if (_numargs() > ARGS_6) {
00362 prsfmt = pform;
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 if (IS_PFORM_BROKEN && pform != NULL) {
00373
00374 if (*(long*)pform == -1)
00375
00376 prsfmt = NULL;
00377 else
00378
00379 prsfmt = (fmt_type**)&pform;
00380 }
00381 }
00382 else
00383 prsfmt = NULL;
00384
00385
00386
00387
00388
00389
00390
00391
00392 fnum = 0;
00393
00394 while (isdigit(*fptr) && flen-- > 0)
00395 fnum = (fnum * 10) + ((int) *fptr++ - ZERO);
00396
00397 css->u.fmt.u.fe.fmtbuf = fptr;
00398 css->u.fmt.u.fe.fmtlen = flen;
00399 css->u.fmt.u.fe.fmtnum = fnum;
00400
00401
00402
00403
00404
00405
00406
00407 if (prsfmt == NULL || *prsfmt == NULL ||
00408 (**prsfmt).offset != PARSER_LEVEL) {
00409
00410 errn = _parse(css, cup, prsfmt);
00411
00412 if (errn != 0) {
00413 ERROR0(errf, errn);
00414 }
00415 }
00416 else
00417 css->u.fmt.u.fe.pfmt = *prsfmt;
00418
00419
00420
00421
00422
00423
00424
00425 stsz = (*css->u.fmt.u.fe.pfmt).rep_count;
00426
00427 if (stsz > cup->upfcstsz) {
00428
00429 cup->upfcstsz = stsz;
00430
00431 if (cup->upfcstk != NULL)
00432 free(cup->upfcstk);
00433
00434 cup->upfcstk = (int *) malloc(sizeof(int) * stsz);
00435
00436 if (cup->upfcstk == NULL) {
00437 errn = FENOMEMY;
00438 ERROR0(errf, errn);
00439 }
00440
00441 }
00442
00443 css->u.fmt.u.fe.pftocs = cup->upfcstk;
00444
00445
00446
00447 css->u.fmt.u.fe.pfcp = css->u.fmt.u.fe.pfmt + 1;
00448
00449
00450
00451 *css->u.fmt.u.fe.pftocs = css->u.fmt.u.fe.pfcp->rep_count;
00452 }
00453
00454
00455
00456 if (iotp == DIR) {
00457
00458 if (cup->useq)
00459 errn = FEDIRTIV;
00460 else
00461 errn = _unit_seek(cup, recn, iost);
00462
00463 if (errn != 0) {
00464 ERROR1(errf, errn, recn);
00465 }
00466
00467 css->u.fmt.endrec = _dr_endrec;
00468 }
00469 else {
00470
00471 if (cup->useq == 0) {
00472 errn = FESEQTIV;
00473 ERROR0(errf, errn);
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 if (iotp == INT) {
00485
00486 css->u.fmt.iiae = ((_numargs() > ARGS_7) &&
00487 (inumelt != NULL)) ? *inumelt : -1;
00488 css->u.fmt.endrec = _ir_endrec;
00489 css->u.fmt.icp = _fcdtocp(funit);
00490 css->u.fmt.icl = _fcdlen (funit);
00491
00492
00493
00494
00495
00496
00497
00498 if (css->u.fmt.icl > cup->urecsize) {
00499
00500 cup->ulinebuf = (long*) realloc(cup->ulinebuf,
00501 sizeof(long) *
00502 (css->u.fmt.icl + 1));
00503
00504 if (cup->ulinebuf == NULL) {
00505 errn = FENOMEMY;
00506 ERROR0(errf, errn);
00507 }
00508 }
00509
00510 cup->urecsize = css->u.fmt.icl;
00511 }
00512 else
00513 css->u.fmt.endrec = _sr_endrec;
00514 }
00515
00516 if (cup->pnonadv == 0) {
00517 errn = (*css->u.fmt.endrec)(css, cup, 1);
00518 }
00519 else {
00520 css->u.fmt.leftablim = cup->ulineptr;
00521 }
00522
00523 if (errn != 0)
00524 if (errn < 0 ) {
00525 ERROR0(endf, errn);
00526 }
00527 else {
00528 ERROR0(errf, errn);
00529 }
00530
00531 cup->pnonadv = 0;
00532
00533
00534
00535 return(CFT77_RETVAL(IO_OKAY));
00536
00537 error:
00538
00539
00540 if (iostat != NULL)
00541 *iostat = errn;
00542
00543 if (cup != NULL)
00544 cup->uflag |= (errn < 0) ? _UENDC : _UERRC;
00545
00546
00547
00548 return(CFT77_RETVAL($RFF()));
00549 }
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567 int
00568 $RFA$(
00569 _fcd fwa,
00570 long *cnt,
00571 long *inc,
00572 long *typ
00573 )
00574 {
00575 register int errn;
00576 type_packet tip;
00577 unit *cup;
00578 void *vaddr;
00579 xfer_func *xfunc;
00580 FIOSPTR css;
00581
00582
00583
00584 GET_FIOS_PTR(css);
00585
00586 cup = css->f_cu;
00587 tip.type77 = *typ & 017;
00588 tip.type90 = _f77_to_f90_type_cnvt[tip.type77];
00589 tip.count = *cnt;
00590 tip.stride = *inc;
00591 tip.intlen = _f77_type_len[tip.type77];
00592 tip.extlen = tip.intlen;
00593 tip.elsize = tip.intlen;
00594 tip.cnvindx = 0;
00595
00596 if (tip.type77 == DT_CHAR) {
00597 vaddr = _fcdtocp(fwa);
00598 tip.elsize = tip.elsize * _fcdlen(fwa);
00599 }
00600 else
00601 vaddr = *(void **) &fwa;
00602
00603 xfunc = (css->f_iostmt & TF_FMT) ? _rdfmt : _ld_read;
00604 errn = xfunc(css, cup, vaddr, &tip, 0);
00605
00606 if (errn == 0)
00607 return(CFT77_RETVAL(IO_OKAY));
00608
00609
00610
00611 if (cup->uiostat != NULL)
00612 *(cup->uiostat) = errn;
00613
00614
00615
00616 cup->uflag |= (errn < 0) ? _UENDC : _UERRC;
00617
00618
00619
00620 return(CFT77_RETVAL($RFF()));
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633 int
00634 $RFF(void)
00635 {
00636 register int errn;
00637 register long flag;
00638 unit *cup;
00639 FIOSPTR css;
00640
00641
00642
00643 GET_FIOS_PTR(css);
00644
00645 cup = css->f_cu;
00646
00647 if (cup == NULL)
00648 flag = _UERRC | _UERRF;
00649
00650 else {
00651
00652
00653
00654 #ifdef _CRAYMPP
00655 if (css->f_shrdput) {
00656 css->f_shrdput = 0;
00657 _remote_write_barrier();
00658 }
00659 #endif
00660 if ((css->f_iostmt & TF_FMT) &&
00661 (cup->uflag & (_UERRC | _UENDC)) == 0) {
00662
00663
00664 errn = _rdfmt(css, cup, (void *) NULL, &__tip_null,
00665 0);
00666
00667 if (errn != 0) {
00668
00669
00670
00671 if (cup->uiostat != NULL)
00672 *(cup->uiostat) = errn;
00673
00674
00675
00676 cup->uflag |= (errn > 0) ? _UERRC : _UENDC;
00677 }
00678 }
00679
00680
00681
00682 if (css->u.fmt.freepfmt && css->u.fmt.u.fe.pfmt != NULL)
00683 free(css->u.fmt.u.fe.pfmt);
00684
00685 flag = cup->uflag;
00686 }
00687
00688 STMT_END(cup, TF_READ, NULL, css);
00689
00690
00691
00692 if ((flag & (_UERRC | _UENDC)) == 0)
00693 return(CFT77_RETVAL(IO_OKAY));
00694 else
00695 if ((flag & _UERRC) != 0) {
00696
00697 if ((flag & (_UIOSTF | _UERRF)) != 0)
00698 return(CFT77_RETVAL(IO_ERR));
00699 }
00700 else
00701 if ((flag & (_UIOSTF | _UENDF)) != 0)
00702 return(CFT77_RETVAL(IO_END));
00703
00704 _ferr(css, FEINTUNK);
00705 }
00706
00707 #endif
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 int
00729 _dr_endrec(FIOSPTR css, unit *cup, int count)
00730 {
00731 register int i;
00732 register int length;
00733 long stat;
00734
00735 assert ( css != NULL );
00736 assert ( cup != NULL );
00737 assert ( count > 0 );
00738
00739 cup->udalast = cup->udalast + count;
00740 length = 0;
00741
00742 if (cup->udalast > cup->udamax)
00743 RERROR1(FENORECN, cup->udalast);
00744
00745 for (i = 0; i < count; i++) {
00746
00747 length = _frch(cup, cup->ulinebuf, cup->urecsize, FULL, &stat);
00748
00749 switch (stat) {
00750
00751 case EOR:
00752 if (length != cup->urecsize) {
00753
00754 }
00755 break;
00756
00757 case EOF:
00758 case EOD:
00759
00760
00761
00762
00763
00764
00765 RERROR1(FENORECN, cup->udalast);
00766
00767 case CNT:
00768
00769
00770
00771
00772
00773
00774 RERROR(FERDMALR);
00775
00776 default:
00777 RERROR(errno);
00778
00779 }
00780 }
00781
00782 cup->ulinecnt = length;
00783 cup->ulineptr = cup->ulinebuf;
00784 css->u.fmt.leftablim = cup->ulinebuf;
00785
00786 return(0);
00787 }
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808 int
00809 _ir_endrec(FIOSPTR css, unit *cup, int count)
00810 {
00811 register int i;
00812
00813 assert ( css != NULL );
00814 assert ( cup != NULL );
00815 assert ( count > 0 );
00816
00817 for (i = 0; i < count; i++) {
00818
00819 if (css->u.fmt.iiae-- == 0)
00820 REND(FERDIEOF);
00821
00822
00823
00824 if (i != (count - 1))
00825 css->u.fmt.icp = css->u.fmt.icp + cup->urecsize;
00826 else
00827 (void) _unpack(css->u.fmt.icp, cup->ulinebuf,
00828 css->u.fmt.icl, -1);
00829
00830 }
00831
00832 css->u.fmt.icp = css->u.fmt.icp + css->u.fmt.icl;
00833 cup->ulinecnt = css->u.fmt.icl;
00834 cup->ulineptr = cup->ulinebuf;
00835 css->u.fmt.leftablim = cup->ulinebuf;
00836
00837 return(0);
00838 }
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859 int
00860 _sr_endrec(FIOSPTR css, unit *cup, int count)
00861 {
00862 register int eofstat;
00863 register long length;
00864 register long offset;
00865 long stat;
00866
00867 assert ( css != NULL );
00868 assert ( cup != NULL );
00869 assert ( count > 0 );
00870
00871 cup->uend = BEFORE_ENDFILE;
00872
00873 while (count > 1) {
00874 long tbuf[2];
00875
00876 length = _frch(cup, tbuf, 1, FULL, &stat);
00877
00878 if (length == IOERR)
00879 RERROR(errno);
00880
00881 switch (stat) {
00882
00883 case EOR:
00884 case CNT:
00885 break;
00886
00887 case EOF:
00888 cup->uend = PHYSICAL_ENDFILE;
00889 REND(FERDPEOF);
00890
00891 case EOD:
00892 if (cup->uend == BEFORE_ENDFILE) {
00893 cup->uend = LOGICAL_ENDFILE;
00894 eofstat = FERDPEOF;
00895 }
00896 else
00897 eofstat = FERDENDR;
00898
00899 REND(eofstat);
00900
00901 default:
00902 RERROR(errno);
00903
00904 }
00905
00906 count = count - 1;
00907 }
00908
00909 offset = 0;
00910
00911 do {
00912
00913 length = _frch(cup, cup->ulinebuf + offset,
00914 cup->urecsize - offset, PARTIAL, &stat);
00915
00916 if (length == IOERR)
00917 RERROR(errno);
00918
00919 switch (stat) {
00920 register long tlen;
00921 long *tptr;
00922
00923 case EOR:
00924 break;
00925
00926 case EOF:
00927 if (offset > 0)
00928 break;
00929
00930 cup->uend = PHYSICAL_ENDFILE;
00931 REND(FERDPEOF);
00932
00933 case EOD:
00934 if (offset > 0)
00935 break;
00936
00937 if (cup->uend == BEFORE_ENDFILE) {
00938 cup->uend = LOGICAL_ENDFILE;
00939 eofstat = FERDPEOF;
00940 }
00941 else
00942 eofstat = FERDENDR;
00943
00944 REND(eofstat);
00945
00946 case CNT:
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963 #define MB 01000000L
00964
00965 if (length != (cup->urecsize - offset)) {
00966
00967
00968
00969
00970
00971
00972 stat = EOR;
00973 break;
00974 }
00975
00976 offset = cup->urecsize;
00977 tlen = offset;
00978
00979 if (tlen >= (MB - 1))
00980 tlen = (((tlen + 1) << 1) &
00981 ~(MB - 1)) - 1;
00982 else {
00983 tlen = tlen << 1;
00984
00985 if (tlen > MB)
00986 tlen = MB - 1;
00987 }
00988
00989 if (tlen < offset)
00990 RERROR(FERDMEMY);
00991
00992 tptr = realloc(cup->ulinebuf, sizeof(long) *
00993 (tlen + 1));
00994
00995 if (tptr == (long *) NULL)
00996 RERROR(FERDMEMY);
00997
00998 cup->ulinebuf = tptr;
00999 cup->urecsize = tlen;
01000
01001 break;
01002
01003 default:
01004 RERROR(errno);
01005
01006 }
01007 } while (stat == CNT);
01008
01009 cup->uend = BEFORE_ENDFILE;
01010 cup->ulinecnt = length + offset;
01011 cup->ulineptr = cup->ulinebuf;
01012 css->u.fmt.leftablim = cup->ulinebuf;
01013
01014 return(0);
01015 }