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