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