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
00039
00040
00041
00042 #pragma ident "@(#) libf/fio/rdfmt.c 92.6 06/21/99 10:37:55"
00043
00044 #include <memory.h>
00045 #include <stdlib.h>
00046 #include <string.h>
00047 #include <fortran.h>
00048 #include <cray/fmtconv.h>
00049 #include <cray/format.h>
00050 #include <cray/nassert.h>
00051 #ifdef _CRAYT3D
00052 #include <cray/mppsdd.h>
00053 #define MAXSH 512
00054 #else
00055 #define MAXSH 1
00056 #endif
00057 #include "fio.h"
00058 #include "fmt.h"
00059 #include "f90io.h"
00060 #include "lio.h"
00061
00062 extern
00063 #ifndef KEY
00064 const
00065 #endif
00066 ic_func *_iconvtab[LAST_DATA_ED + 1];
00067 extern const short _idedtab[DVTYPE_NTYPES];
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 int
00091 _rdfmt(
00092 FIOSPTR css,
00093 unit *cup,
00094 void *dptr,
00095 type_packet *tip,
00096 int _Unused
00097 )
00098 {
00099 register short cswitch;
00100 register short fmtop;
00101 register short part;
00102 register ftype_t type;
00103 register int32 chxfer;
00104 register int32 delta;
00105 register int32 field;
00106 register int32 i;
00107 register int32 itemch;
00108 register int32 kount;
00109 register int32 length;
00110 register int32 padcnt;
00111 register int32 repcnt;
00112 int cinc[2];
00113 register int stat;
00114 register int stride;
00115 register char *cptr;
00116 register char *ctmp;
00117 long digits;
00118 long mode;
00119 long *tptr;
00120 long width;
00121 register long count;
00122 register long dfmode;
00123 fmt_type pfmt;
00124 #ifdef _CRAYT3D
00125 register short shared;
00126 register int elwords;
00127 register int offset;
00128 register int32 tcount;
00129 long shrd[MAXSH];
00130 #endif
00131
00132 int _nicverr(
00133 const int _Nicverror);
00134
00135 #ifndef KEY
00136 const
00137 #endif
00138 ic_func *ngcf;
00139
00140
00141
00142 assert (cup != NULL);
00143 assert (tip != NULL);
00144
00145 type = tip->type90;
00146 count = tip->count;
00147
00148 chxfer = 0;
00149 cswitch = 0;
00150 stat = 0;
00151 part = 1;
00152
00153 pfmt = *css->u.fmt.u.fe.pfcp;
00154 repcnt = *css->u.fmt.u.fe.pftocs;
00155 length = tip->elsize;
00156 stride = tip->stride * length;
00157 cinc[1] = stride;
00158
00159
00160
00161 if (type == DVTYPE_COMPLEX) {
00162 length = length / 2;
00163 cinc[0] = length;
00164 cinc[1] = stride - length;
00165 cswitch = 1;
00166 part = 0;
00167 }
00168
00169 dfmode = ((css->u.fmt.blank0 == 1) ? MODEBZ : MODEBN);
00170
00171 #ifdef _CRAYT3D
00172 if (_issddptr(dptr)) {
00173 offset = 0;
00174 elwords = tip->elsize / sizeof(long);
00175 shared = 1;
00176 stride = tip->elsize;
00177 tcount = count;
00178 css->f_shrdput = 1;
00179 }
00180 else
00181 shared = 0;
00182
00183 do {
00184 if (shared) {
00185
00186
00187
00188
00189
00190 count = MIN (MAXSH / elwords, (tcount - offset));
00191 cptr = (char *) shrd;
00192 }
00193 else
00194 #endif
00195 {
00196 cptr = (char *) dptr;
00197 }
00198
00199 do {
00200
00201 fmtop = pfmt.op_code;
00202 width = pfmt.field_width;
00203 digits = pfmt.digits_field;
00204
00205
00206
00207 if (fmtop > LAST_OP || fmtop < FIRST_DATA_ED) {
00208 stat = FEINTIPF;
00209 goto done;
00210 }
00211
00212 if (fmtop <= LAST_DATA_ED) {
00213
00214
00215
00216
00217
00218
00219 if (count == 0)
00220 goto done;
00221
00222
00223
00224
00225
00226
00227
00228 if (INVALID_RTYPE(fmtop, type)) {
00229 stat = FERDTYPE;
00230 goto done;
00231 }
00232
00233 if (fmtop == G_ED) {
00234
00235 fmtop = _idedtab[type];
00236
00237 if (type != DVTYPE_REAL &&
00238 type != DVTYPE_COMPLEX)
00239 digits = 1;
00240 }
00241
00242 if (type == DVTYPE_ASCII)
00243 mode = 0;
00244 else {
00245 mode = (long) _rd_ilchk[fmtop-1][length-1];
00246
00247 if (mode == INVALID_INTLEN) {
00248 stat = FERDTYPE;
00249 goto done;
00250 }
00251 }
00252
00253 mode = mode | dfmode;
00254
00255
00256
00257
00258
00259 if (width == 0) {
00260 register int exp;
00261
00262 switch (fmtop) {
00263
00264
00265
00266
00267
00268
00269 case A_ED:
00270 case R_ED:
00271 width = length;
00272 break;
00273
00274
00275
00276
00277
00278
00279
00280 case B_ED:
00281 case I_ED:
00282 case O_ED:
00283 case Z_ED:
00284 width = _rw_mxdgt[fmtop-1][length-1];
00285
00286
00287
00288 if (width == 127)
00289 width = 128;
00290
00291
00292
00293 width = width + 1;
00294
00295 if (fmtop == I_ED)
00296 width = width + 1;
00297
00298 if (pfmt.default_digits)
00299 digits = 1;
00300 break;
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 case D_ED:
00313 case E_ED:
00314 case EN_ED:
00315 case ES_ED:
00316 case F_ED:
00317 case G_ED:
00318 if (pfmt.default_digits)
00319 digits = _rw_mxdgt[fmtop-1][length-1];
00320
00321 if (length == 16)
00322 exp = DEXP16;
00323 #ifdef _F_REAL4
00324 else if (length == 4)
00325 exp = DEXP4;
00326 #endif
00327 else
00328 exp = DEXP8;
00329
00330 width = digits + exp + 6;
00331 break;
00332
00333
00334
00335
00336
00337
00338 case L_ED:
00339 width = _rw_mxdgt[fmtop-1][length-1];
00340 break;
00341
00342
00343
00344
00345
00346 case Q_ED:
00347 width = 0;
00348 break;
00349
00350
00351
00352
00353 default:
00354 width = -1;
00355 break;
00356 }
00357
00358
00359
00360
00361 if (width < 0) {
00362 stat = FERDTYPE;
00363 goto done;
00364 }
00365 }
00366
00367
00368
00369
00370
00371 if (cup->uend) {
00372 stat = FERDPEOF;
00373 goto done;
00374 }
00375
00376
00377
00378
00379
00380
00381
00382 kount = MIN(repcnt,
00383 ((count << cswitch) - (part & cswitch)));
00384 field = width * kount;
00385
00386
00387
00388
00389
00390
00391
00392 if (field > cup->ulinecnt) {
00393
00394 field = width;
00395 kount = 1;
00396
00397 if (width > cup->ulinecnt) {
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 if (css->u.fmt.nonadv)
00409 stat = FEEORCND;
00410 else
00411 if (cup->upad == OS_NO)
00412 stat = FERDPEOR;
00413
00414
00415
00416
00417
00418
00419
00420 if (cup->ulinecnt <= 0 &&
00421 cup->upad == OS_NO)
00422 goto done;
00423 }
00424 }
00425 }
00426
00427 switch (fmtop) {
00428
00429
00430
00431 case B_ED:
00432 case D_ED:
00433 case E_ED:
00434 case EN_ED:
00435 case ES_ED:
00436 case F_ED:
00437 case G_ED:
00438 case I_ED:
00439 case L_ED:
00440 case O_ED:
00441 case Z_ED:
00442
00443 ngcf = _iconvtab[fmtop];
00444
00445 #ifdef _CRAY
00446 #pragma _CRI align
00447 #endif
00448
00449 for (i = 0; i < kount; i++) {
00450 register short j;
00451 long nstat;
00452
00453
00454
00455 if (length > sizeof(int))
00456 for (j = 1; j < (length/sizeof(int)); j++)
00457 ((int *) cptr)[j] = 0;
00458
00459 itemch = MIN(MAX(0, cup->ulinecnt), width);
00460 tptr = cup->ulineptr + itemch;
00461 nstat = -1;
00462
00463 (void) ngcf(cup->ulineptr, &width, &tptr, &mode,
00464 cptr, &nstat, &digits,
00465 &css->u.fmt.u.fe.scale);
00466
00467 if (nstat < 0) {
00468 #ifdef KEY
00469
00470
00471 if (EX_ILLCHAR == nstat &&
00472 ',' == (*(char *)tptr)) {
00473 itemch = (tptr - cup->ulineptr) + 1;
00474 }
00475 else {
00476 stat = _nicverr(nstat);
00477 if (stat > 0)
00478 goto done;
00479 }
00480 #else
00481 stat = _nicverr(nstat);
00482 if (stat > 0)
00483 goto done;
00484 #endif
00485 }
00486
00487
00488
00489 cup->ulineptr = cup->ulineptr + itemch;
00490 cup->ulinecnt = cup->ulinecnt - itemch;
00491 chxfer = chxfer + itemch;
00492 count = count - part;
00493 cptr = cptr + cinc[part];
00494 part = part ^ cswitch;
00495 }
00496
00497 repcnt = repcnt - kount;
00498
00499 break;
00500
00501
00502
00503 case A_ED:
00504 case R_ED:
00505
00506 delta = length - width;
00507
00508
00509
00510
00511
00512
00513
00514 if (delta == 0 && tip->stride == 1 && cswitch == 0) {
00515
00516 itemch = MIN(MAX(0, cup->ulinecnt), field);
00517
00518 (void) _pack(cup->ulineptr, cptr, itemch, -1);
00519
00520 padcnt = field - itemch;
00521
00522 if (padcnt > 0)
00523 (void) memset(cptr + itemch, BLANK, (size_t) padcnt);
00524
00525 cup->ulineptr = cup->ulineptr + itemch;
00526 cup->ulinecnt = cup->ulinecnt - itemch;
00527 chxfer = chxfer + itemch;
00528 count = count - kount;
00529 cptr = cptr + (stride * kount);
00530 }
00531 else
00532
00533 #ifdef _CRAY
00534 #pragma _CRI align
00535 #endif
00536
00537 for (i = 0; i < kount; i++) {
00538
00539 ctmp = cptr;
00540 itemch = MIN(MAX(0, cup->ulinecnt), width);
00541
00542
00543
00544
00545
00546
00547
00548
00549 if (delta < 0) {
00550 itemch = itemch + delta;
00551 cup->ulinecnt = cup->ulinecnt + delta;
00552 cup->ulineptr = cup->ulineptr - delta;
00553 padcnt = (delta + width) - itemch;
00554 }
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 else {
00565 padcnt = delta + (width - itemch);
00566
00567 if (fmtop == R_ED && delta > 0) {
00568 register int fill;
00569
00570 fill = (type == DVTYPE_ASCII) ?
00571 BLANK : 0;
00572
00573 (void) memset(ctmp, fill, (size_t) delta);
00574
00575 ctmp = ctmp + delta;
00576 padcnt = padcnt - delta;
00577 }
00578 }
00579
00580
00581
00582 if (itemch > 0)
00583 (void) _pack(cup->ulineptr, ctmp, itemch, -1);
00584
00585
00586
00587
00588
00589
00590
00591 if (padcnt > 0)
00592 (void) memset(ctmp + itemch, BLANK, (size_t) padcnt);
00593
00594
00595
00596 cup->ulineptr = cup->ulineptr + itemch;
00597 cup->ulinecnt = cup->ulinecnt - itemch;
00598 chxfer = chxfer + itemch;
00599 count = count - part;
00600 cptr = cptr + cinc[part];
00601 part = part ^ cswitch;
00602 }
00603
00604 repcnt = repcnt - kount;
00605 break;
00606
00607 case Q_ED:
00608 if (length == 4)
00609 *(_f_int4 *)cptr = MAX(cup->ulinecnt, 0);
00610 else if (length == 8)
00611 *(_f_int8 *)cptr = MAX(cup->ulinecnt, 0);
00612 else if (length == 2)
00613 *(_f_int2 *)cptr = MAX(cup->ulinecnt, 0);
00614 else
00615 *(_f_int1 *)cptr = MAX(cup->ulinecnt, 0);
00616
00617
00618
00619 count = count - part;
00620 cptr = cptr + cinc[part];
00621 part = part ^ cswitch;
00622 repcnt = repcnt - 1;
00623 break;
00624
00625 case SLASH_ED:
00626 stat = (*css->u.fmt.endrec)(css, cup, width);
00627 repcnt = repcnt - 1;
00628 break;
00629
00630 case TR_ED:
00631 cup->ulineptr = cup->ulineptr + width;
00632 cup->ulinecnt = cup->ulinecnt - width;
00633 repcnt = repcnt - 1;
00634 break;
00635
00636 case T_ED:
00637 tptr = cup->ulineptr;
00638 cup->ulineptr = css->u.fmt.leftablim + width - 1;
00639 cup->ulinecnt = cup->ulinecnt + (tptr - cup->ulineptr);
00640 repcnt = 0;
00641 break;
00642
00643 case TL_ED:
00644 cup->ulineptr = cup->ulineptr - width;
00645 cup->ulinecnt = cup->ulinecnt + width;
00646
00647
00648
00649
00650 if (cup->ulineptr < css->u.fmt.leftablim) {
00651 cup->ulinecnt = cup->ulinecnt -
00652 (css->u.fmt.leftablim - cup->ulineptr);
00653 cup->ulineptr = css->u.fmt.leftablim;
00654 }
00655 repcnt = repcnt - 1;
00656 break;
00657
00658 case STRING_ED:
00659
00660
00661
00662
00663
00664 # ifdef KEY
00665 cup->ulineptr += width;
00666 # else
00667 stat = FEFMTLII;
00668 # endif
00669 repcnt = repcnt - 1;
00670 break;
00671
00672 case BN_ED:
00673 css->u.fmt.blank0 = 0;
00674 dfmode = dfmode & ~MODEBZ;
00675 dfmode = dfmode | MODEBN;
00676 repcnt = 0;
00677 break;
00678
00679 case BZ_ED:
00680 css->u.fmt.blank0 = 1;
00681 dfmode = dfmode & ~MODEBN;
00682 dfmode = dfmode | MODEBZ;
00683 repcnt = 0;
00684 break;
00685
00686 case DOLLAR_ED:
00687 case S_ED:
00688 case SS_ED:
00689 case SP_ED:
00690 repcnt = 0;
00691 break;
00692
00693 case P_ED:
00694 css->u.fmt.u.fe.scale = pfmt.rep_count;
00695 repcnt = 0;
00696 break;
00697
00698 case COLON_ED:
00699
00700
00701
00702
00703 if (count == 0)
00704 goto done;
00705
00706 repcnt = 0;
00707 break;
00708
00709 case REPEAT_OP:
00710
00711
00712
00713
00714 *css->u.fmt.u.fe.pftocs++ = pfmt.rep_count;
00715 repcnt = 0;
00716 break;
00717
00718 case ENDREP_OP:
00719
00720
00721
00722
00723
00724
00725
00726
00727 if ( --(*(css->u.fmt.u.fe.pftocs - 1)) < 1)
00728 css->u.fmt.u.fe.pftocs--;
00729 else
00730 css->u.fmt.u.fe.pfcp = css->u.fmt.u.fe.pfcp +
00731 pfmt.rep_count;
00732
00733 repcnt = repcnt - 1;
00734
00735 break;
00736
00737 case REVERT_OP:
00738
00739
00740
00741
00742
00743
00744 if (pfmt.rgcdedf == 0 && count > 0)
00745 stat = FEFMTILF;
00746 else {
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758 if (count == 0)
00759 goto done;
00760
00761
00762
00763 stat = (*css->u.fmt.endrec)(css, cup, 1);
00764 repcnt = 0;
00765
00766
00767
00768 css->u.fmt.u.fe.pfcp = css->u.fmt.u.fe.pfcp +
00769 pfmt.rep_count - 1;
00770 }
00771 break;
00772
00773 default:
00774 stat = FEINTIPF;
00775 break;
00776
00777 }
00778
00779
00780
00781
00782
00783
00784 if (stat == 0 && repcnt < 1) {
00785
00786 if (fmtop == STRING_ED)
00787 css->u.fmt.u.fe.pfcp = css->u.fmt.u.fe.pfcp +
00788 ((width +
00789 FMT_ENTRY_BYTE_SIZE - 1) /
00790 FMT_ENTRY_BYTE_SIZE);
00791
00792 css->u.fmt.u.fe.pfcp = css->u.fmt.u.fe.pfcp + 1;
00793 pfmt = *css->u.fmt.u.fe.pfcp;
00794 repcnt = pfmt.rep_count;
00795 css->u.fmt.u.fe.fmtcol = pfmt.offset;
00796 }
00797
00798 } while (stat == 0);
00799 done:
00800
00801 #ifdef _CRAYT3D
00802 if (shared && ((long *) cptr != shrd)) {
00803 register int items;
00804
00805
00806
00807 items = ((long *) cptr - shrd) / elwords;
00808 (void) _cpytosdd(dptr, shrd, items, elwords, tip->stride, offset);
00809 offset = offset + items;
00810 }
00811
00812 } while (stat == 0 && shared && offset < tcount);
00813 #endif
00814
00815
00816
00817 *css->u.fmt.u.fe.pftocs = repcnt;
00818
00819 if (css->u.fmt.nonadv)
00820 css->u.fmt.u.fe.charcnt = css->u.fmt.u.fe.charcnt + chxfer;
00821
00822
00823
00824 if (stat == FEEORCND) {
00825 if ((cup->uflag & (_UEORF | _UIOSTF)) == 0)
00826 _ferr(css, stat);
00827
00828 cup->pnonadv = 0;
00829 }
00830 else if (stat > 0) {
00831 if ((cup->uflag & (_UERRF | _UIOSTF)) == 0)
00832 _ferr(css, stat);
00833 }
00834 else if (stat < 0) {
00835 if ((cup->uflag & (_UENDF | _UIOSTF)) == 0)
00836 _ferr(css, stat);
00837 }
00838
00839 return(stat);
00840 }
00841
00842 #if defined(BUILD_OS_DARWIN)
00843 #elif defined(__mips) || (defined(_LITTLE_ENDIAN) && defined(__sv2))
00844 #include <ieeefp.h>
00845 #elif defined(_LITTLE_ENDIAN) && !(__sv2)
00846 #include <fpu_control.h>
00847 #endif
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858 int
00859 _nicverr(const int nicverror)
00860 {
00861 int errn;
00862
00863 switch (nicverror) {
00864 case EX_ILLCHAR:
00865 errn = FENICVIC;
00866 break;
00867 case EX_FIXOFLO:
00868 errn = FENICVOF;
00869 break;
00870 case EX_EXPUFLO:
00871 errn = FENICVEU;
00872 #if defined(__mips) || (defined(_LITTLE_ENDIAN) && defined(__sv2))
00873
00874 if ((fpgetmask() & FP_X_UFL) == 0)
00875 errn = 0;
00876 #elif defined (_LITTLE_ENDIAN) && !defined(__sv2)
00877 errn = 0;
00878 #endif
00879 break;
00880 case EX_EXPOFLO:
00881 errn = FENICVEO;
00882 #if defined(__mips) || (defined(_LITTLE_ENDIAN) && defined(__sv2))
00883
00884 if ((fpgetmask() & FP_X_OFL) == 0)
00885 errn = 0;
00886 #elif defined (_LITTLE_ENDIAN) && !defined(__sv2)
00887 errn = 0;
00888 #endif
00889 break;
00890 case EX_NULLFLD:
00891 errn = FENICVBK;
00892 break;
00893 case EX_INVLOGI:
00894 errn = FERDIVLG;
00895 break;
00896 default:
00897 errn = FEINTUNK;
00898 break;
00899 }
00900
00901 return(errn);
00902 }