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/wnly.c 92.1 06/21/99 10:37:55"
00043
00044
00045
00046
00047
00048 #include <stdio.h>
00049 #include <errno.h>
00050 #include <fortran.h>
00051 #include <memory.h>
00052 #include <malloc.h>
00053 #include <liberrno.h>
00054 #include <stdlib.h>
00055 #include <cray/fmtconv.h>
00056 #include "fio.h"
00057 #include "fmt.h"
00058 #include "lio.h"
00059 #include "rnl.h"
00060
00061 extern void _memwcpy (long *_S1, long *_S2, int _N);
00062
00063
00064
00065
00066
00067
00068
00069 #define YMP80 (_dreal8 == DREAL8_YMP80)
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 struct BUFFERS {
00082 long *outbuff;
00083 long *outptr;
00084 int outcnt;
00085 long *f_lbuf;
00086 long *f_lbufptr;
00087 int f_lbufcnt;
00088 int lcomma;
00089 };
00090
00091 static char *char_rep(char *_P, int _Cn, unsigned int _Ln, int *_Lc,
00092 struct BUFFERS *_Bp);
00093
00094 static long *find_rep(long *_P, int _Cn, int _In, int _Ty, int *_Lc,
00095 struct BUFFERS *_Bp);
00096
00097 static int l_write(FIOSPTR css, unit *cup, void *dptr, unsigned elsize,
00098 int count, int inc, int type, long recsize, int errf,
00099 struct BUFFERS *bptr);
00100
00101 static int lw_A(FIOSPTR css, char *_P, int _Cl, long _Rc, unit *_Cu,
00102 int _Er, struct BUFFERS *_Bp);
00103
00104 static void writ_rep(long repcnt, struct BUFFERS *buffers);
00105
00106
00107
00108
00109
00110 #define NLPUT(x) { \
00111 *(bptr->outptr)++ = (long) x; \
00112 bptr->outcnt--; \
00113 }
00114
00115 #define NLPUTS(string) { \
00116 s = string; \
00117 while (c = *s++) { \
00118 NLPUT(c); \
00119 } \
00120 }
00121
00122
00123
00124
00125
00126 #define LPUT(x) { \
00127 (*(bptr->f_lbufptr)++ = (long) x); \
00128 bptr->f_lbufcnt++; \
00129 }
00130
00131 #define LPUTS(string) { \
00132 s = string; \
00133 while (c = *s++) { \
00134 LPUT(c); \
00135 } \
00136 }
00137
00138
00139
00140
00141
00142 #define NLINE() { \
00143 bptr->lcomma = 0; \
00144 if (OUT_LINE) { \
00145 REPFLUSH(); \
00146 } \
00147 }
00148
00149
00150
00151
00152
00153
00154
00155 #define REPFLUSH() { \
00156 if (_fwch(cup, bptr->outbuff, recsize - bptr->outcnt, 1) < 0)\
00157 RERR(css, errno); \
00158 bptr->outptr = bptr->outbuff;\
00159 *bptr->outptr++ = (long) ' '; \
00160 *bptr->outptr++ = (long) ' '; \
00161 bptr->outcnt = recsize - 2; \
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 int
00179 @WNL(
00180 _f_int *unump,
00181 Namelist *nl,
00182 int errf
00183 )
00184 {
00185 unum_t unum;
00186 int errn;
00187 int n, ss;
00188 void *vaddr;
00189 unsigned elsize;
00190 long recsize;
00191
00192 char c;
00193 char *s;
00194 unit *cup;
00195 Nlentry *nlent;
00196 FIOSPTR css;
00197 struct BUFFERS wnlbuffers;
00198 struct BUFFERS *bptr;
00199 bptr = &wnlbuffers;
00200 bptr->f_lbuf = NULL;
00201
00202 unum = *unump;
00203
00204 GET_FIOS_PTR(css);
00205 STMT_BEGIN(unum, 0, T_WNL, NULL, css, cup);
00206
00207 if (cup == NULL) {
00208 cup = _imp_open77(css, SEQ, FMT, unum, errf, &errn);
00209
00210
00211
00212
00213 if (cup == NULL)
00214 RERR(css, errn);
00215 }
00216
00217
00218
00219 cup->uflag = (errf != 0 ? _UERRF : 0);
00220 cup->ulineptr = cup->ulinebuf;
00221 cup->uwrt = 1;
00222
00223
00224
00225 css->u.fmt.nonl = 0;
00226
00227
00228 if (cup->useq == 0)
00229 RERR(css, FESEQTIV);
00230
00231 if (!cup->ufmt)
00232 RERR(css, FEFMTTIV);
00233
00234 if ((cup->uaction & OS_WRITE) == 0)
00235 RERR(css, FENOWRIT);
00236
00237 bptr = &wnlbuffers;
00238 bptr->lcomma = 0;
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 recsize = cup->uldwsize;
00253
00254 if (cup->urecl == 0 && _wnlrecsiz > 0)
00255 recsize = MIN(cup->urecsize, _wnlrecsiz);
00256
00257 bptr->outcnt = recsize - 1;
00258 bptr->outbuff = cup->ulinebuf;
00259 bptr->outptr = bptr->outbuff;
00260 *bptr->outptr++ = OUT_ECHO;
00261 bptr->f_lbuf = (long *) malloc((recsize + 1) * sizeof(long));
00262
00263 if (bptr->f_lbuf == NULL)
00264 RERR(css, FENOMEMY);
00265
00266
00267
00268 NLPUT(OUT_CHAR);
00269 NLPUTS(nl->nlname);
00270 NLPUT(' ');
00271 NLPUT(' ');
00272 NLINE();
00273
00274 nlent = nl->nlvnames;
00275
00276 do {
00277 int ntype;
00278
00279 ntype = _old_namelist_to_f77_type_cnvt[nlent->na.type];
00280
00281
00282
00283
00284
00285
00286
00287
00288 bptr->f_lbufptr = bptr->f_lbuf;
00289 bptr->f_lbufcnt = 0;
00290
00291 LPUTS(nlent->varname);
00292 LPUT(' ');
00293 LPUT(OUT_EQ);
00294
00295
00296 n = (nlent->na.offdim) ? nlent->na.nels : 1;
00297
00298 if (ntype == DT_CHAR) {
00299 _fcd f;
00300 f = *(_fcd *)(((unsigned long) nlent->va.varaddr +
00301 (long *)nl));
00302 vaddr = _fcdtocp(f);
00303 elsize = _fcdlen(f);
00304 }
00305 else {
00306 vaddr = (void *)nlent->va.varaddr;
00307 elsize = 0;
00308 }
00309
00310 LPUT(' ');
00311
00312
00313
00314 ss = l_write(css, cup, vaddr, elsize, n, 1, ntype, recsize,
00315 errf, bptr);
00316
00317 if (ss != 0) {
00318 RERR(css, ss);
00319 }
00320
00321 NLINE();
00322
00323 nlent++;
00324
00325 } while (nlent->varname[0]);
00326
00327 if (bptr->outcnt < 6) {
00328 REPFLUSH();
00329 bptr->outptr--;
00330 bptr->outcnt++;
00331 }
00332
00333 NLPUT(OUT_CHAR);
00334 NLPUTS("END");
00335 REPFLUSH();
00336 ret:
00337
00338 STMT_END(cup, T_WNL, NULL, css);
00339
00340 if (bptr->f_lbuf != NULL)
00341 free(bptr->f_lbuf);
00342
00343 return(CFT77_RETVAL(ss));
00344 }
00345
00346
00347
00348
00349
00350 static int
00351 l_write(
00352 FIOSPTR css,
00353 unit *cup,
00354 void *dptr,
00355 unsigned elsize,
00356 int count,
00357 int inc,
00358 int type,
00359 long recsize,
00360 int errf,
00361 struct BUFFERS *bptr
00362 )
00363 {
00364 unsigned int len77;
00365 char *cp;
00366 long *ptr;
00367 long ugly[ITEMBUFSIZ];
00368 long dig;
00369 long exp;
00370 long mod;
00371 long scl;
00372 long ss;
00373 long wid;
00374 long *ib_ptr;
00375 long *newp;
00376 int lcount;
00377 oc_func *gcf;
00378 ftype_t f90type;
00379
00380 if (type == DT_CHAR) {
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 cp = dptr;
00391 len77 = elsize;
00392
00393 for (; count > 0; count-- ) {
00394
00395 bptr->lcomma = 0;
00396
00397 if (count > 1) {
00398
00399
00400
00401
00402 cp = char_rep(cp, count, len77, &lcount,
00403 bptr);
00404 count = count - (lcount - 1);
00405 }
00406
00407
00408
00409 ss = lw_A(css, cp, len77, recsize, cup, errf, bptr);
00410
00411 if (ss != 0) {
00412 RERR(css, ss);
00413 }
00414
00415 cp = cp + len77;
00416 }
00417
00418 return(0);
00419
00420 }
00421
00422
00423
00424 ptr = (long *)dptr;
00425 f90type = _f77_to_f90_type_cnvt[type];
00426
00427 if ((type == DT_DBLE) || (type == DT_CMPLX))
00428 inc = inc + inc;
00429
00430 for (; count > 0; count--, ptr += inc) {
00431
00432 if (count > 1) {
00433
00434 ptr = find_rep(ptr, count, inc, type, &lcount,
00435 bptr);
00436
00437 count = count - (lcount - 1);
00438 }
00439
00440 ib_ptr = bptr->f_lbufptr;
00441
00442 switch (type) {
00443
00444 case DT_NONE:
00445 gcf = _s2uo; mod = MODEUN; wid = WOCTWRD;
00446 dig = WOCTWRD; exp = 0; scl = 0;
00447 break;
00448
00449 case DT_SINT:
00450 case DT_INT:
00451 gcf = _s2ui; mod = 0; wid = WINT;
00452 dig = 1; exp = 0; scl = 0;
00453 break;
00454
00455 case DT_REAL:
00456 case DT_CMPLX:
00457 gcf = _sd2uge; mod = 0; wid = WREAL8;
00458 dig = _dreal8; exp = DEXP8; scl = 1;
00459 if (YMP80) dig = 9;
00460 break;
00461
00462 case DT_DBLE:
00463
00464
00465
00466
00467
00468
00469 gcf = _sd2udee; mod = MODEDP; wid = WREAL16;
00470 dig = _dreal16-1; exp = DEXP16; scl = 1;
00471 if (YMP80) dig = 25;
00472 break;
00473 }
00474
00475
00476
00477
00478
00479 switch (type) {
00480
00481 default:
00482
00483 #if _F_REAL16 == 1
00484 if (YMP80 && !cup->uft90 && type == DT_DBLE &&
00485 *(_f_dble *)ptr == 0.0) {
00486
00487 static const char *zero_dp = "0.0E+00";
00488 ib_ptr += _unpack(zero_dp, ib_ptr,
00489 strlen(zero_dp), -1);
00490 break;
00491 }
00492 #endif
00493
00494 newp = gcf(ptr, ugly, &mod, &wid, &dig, &exp, &scl);
00495
00496 if (type == DT_NONE)
00497 *newp++ = 'B';
00498
00499 ib_ptr = ib_ptr + _wnl_beautify(f90type, ugly, newp,
00500 ib_ptr, cup->uft90);
00501 break;
00502
00503 case DT_CMPLX:
00504
00505 *ib_ptr++ = '(';
00506
00507 newp = gcf(ptr, ugly, &mod, &wid, &dig, &exp, &scl);
00508
00509 ib_ptr = ib_ptr + _wnl_beautify(f90type, ugly, newp,
00510 ib_ptr, cup->uft90);
00511
00512 *ib_ptr++ = COMMA;
00513
00514 newp = gcf((_f_real *)ptr + 1, ugly,
00515 &mod, &wid, &dig, &exp, &scl);
00516
00517 ib_ptr = ib_ptr + _wnl_beautify(f90type, ugly, newp,
00518 ib_ptr, cup->uft90);
00519
00520 *ib_ptr++ = ')';
00521
00522 break;
00523
00524 case DT_LOG:
00525 *ib_ptr++ = _lvtob(*(_f_log8 *)ptr)? 'T':'F';
00526 break;
00527 }
00528
00529
00530
00531
00532 bptr->f_lbufcnt += ib_ptr - bptr->f_lbufptr;
00533 bptr->f_lbufptr = ib_ptr;
00534
00535 LPUT(OUT_SEP);
00536 LPUT(' ');
00537 LPUT(' ');
00538
00539 if (bptr->outcnt <= bptr->f_lbufcnt) {
00540
00541
00542
00543
00544
00545
00546 REPFLUSH();
00547 }
00548
00549 bptr->f_lbufptr = bptr->f_lbuf;
00550
00551 _memwcpy(bptr->outptr, bptr->f_lbufptr, bptr->f_lbufcnt);
00552
00553 bptr->outptr += bptr->f_lbufcnt;
00554 bptr->outcnt -= bptr->f_lbufcnt;
00555 bptr->f_lbufptr = bptr->f_lbuf;
00556 bptr->f_lbufcnt = 0;
00557 }
00558
00559 return(0);
00560
00561 ret:
00562 return(ss);
00563 }
00564
00565 static int dont_display_repeats;
00566
00567 static void should_display_repeats(void) __attribute__((constructor));
00568
00569 static void should_display_repeats(void)
00570 {
00571 dont_display_repeats = getenv("FTN_SUPPRESS_REPEATS") != NULL;
00572 }
00573
00574
00575
00576
00577
00578
00579
00580 static long *
00581 find_rep(
00582 long *ptr,
00583 int count,
00584 int inc,
00585 int type,
00586 int *lcount,
00587 struct BUFFERS *bptr
00588 )
00589 {
00590 int i;
00591 long *p1, *p2, *q1, *q2;
00592
00593 if (dont_display_repeats) {
00594 *lcount = 1;
00595 return ptr;
00596 }
00597
00598 p1 = ptr;
00599 q1 = ptr + inc;
00600
00601 if (type == DT_CMPLX || type == DT_DBLE) {
00602
00603 p2 = p1 + 1;
00604 q2 = q1 + 1;
00605
00606 for (i = 1; i < count; i++) {
00607
00608 if ((*p1 != *q1) || (*p2 != *q2)) {
00609 break;
00610 }
00611 else {
00612 p1 = q1;
00613 p2 = p1 + 1;
00614 q1 = q1 + inc;
00615 q2 = q1 + 1;
00616 }
00617 }
00618 }
00619 else {
00620 for (i = 1; i < count; i++) {
00621
00622 if (*p1 != *q1) {
00623 break;
00624 }
00625 else {
00626 p1 = q1;
00627 q1 = q1 + inc;
00628 }
00629 }
00630 }
00631
00632 *lcount = (long) i;
00633
00634 if (i > 1)
00635 writ_rep(i, bptr);
00636
00637 return(p1);
00638 }
00639
00640 static void
00641 writ_rep(
00642 long repcnt,
00643 struct BUFFERS *bptr
00644 )
00645 {
00646 long mode;
00647 long wid;
00648 long dig;
00649 long zero = 0;
00650 long *newp;
00651 long *q;
00652 long buf[WINT];
00653
00654 mode = 0;
00655 wid = WINT;
00656 dig = 0;
00657
00658 newp = _s2ui((long*)&repcnt, buf, &mode, &wid, &dig, &zero, &zero);
00659
00660 for (q = buf; q < newp; q++)
00661 if ((char)*q != ' ')
00662 break;
00663
00664 while (q < newp) {
00665 *bptr->f_lbufptr++ = *q++;
00666 bptr->f_lbufcnt++;
00667 }
00668
00669 *bptr->f_lbufptr++ = (long) '*';
00670 bptr->f_lbufcnt++;
00671 }
00672
00673
00674
00675
00676
00677
00678
00679 static char *
00680 char_rep(
00681 char *ptr,
00682 int count,
00683 unsigned int len77,
00684 int *lcount,
00685 struct BUFFERS *bptr
00686 )
00687 {
00688 int i;
00689 char *qptr;
00690
00691 qptr = ptr + len77;
00692
00693 for (i = 1; i < count; i++) {
00694
00695 if (memcmp(ptr, qptr, len77))
00696 break;
00697
00698 qptr = qptr + len77;
00699 }
00700
00701 *lcount = (long)i;
00702
00703 if (i > 1)
00704 writ_rep(i, bptr);
00705
00706 return(ptr + (*lcount - 1) * len77);
00707 }
00708
00709
00710
00711
00712
00713 static int
00714 lw_A(
00715 FIOSPTR css,
00716 char *ptr,
00717 int charlen,
00718 long recsize,
00719 unit *cup,
00720 int errf,
00721 struct BUFFERS *bptr
00722 )
00723 {
00724 int m;
00725 char *aposptr;
00726 int ss;
00727 int fflag;
00728 int recmax;
00729
00730
00731
00732
00733
00734
00735
00736 fflag = 0;
00737 *bptr->f_lbufptr++ = (long) '\'';
00738 bptr->f_lbufcnt++;
00739
00740 for (; charlen > 0; ) {
00741
00742 if (fflag == 0) {
00743 recmax = recsize - 2;
00744 m = MIN(charlen, recmax - bptr->f_lbufcnt);
00745 }
00746 else {
00747 recmax = recsize - 1;
00748 m = MIN(charlen, recmax - bptr->f_lbufcnt);
00749 }
00750
00751
00752
00753 aposptr = memchr(ptr, '\'', m);
00754
00755 if (aposptr != 0) {
00756
00757 m = aposptr + 1 - ptr;
00758
00759
00760 (void) _unpack(ptr, bptr->f_lbufptr, m, -1);
00761
00762 *(bptr->f_lbufptr + m) = '\'';
00763 ptr = ptr + m;
00764 charlen = charlen - m;
00765 m++;
00766 }
00767 else {
00768
00769
00770 (void) _unpack(ptr, bptr->f_lbufptr, m, -1);
00771
00772 ptr = ptr + m;
00773 charlen = charlen - m;
00774 }
00775
00776 bptr->f_lbufptr += m;
00777 bptr->f_lbufcnt += m;
00778
00779
00780
00781
00782
00783 if (bptr->f_lbufcnt >= recmax) {
00784 if (bptr->outcnt <= bptr->f_lbufcnt) {
00785 REPFLUSH();
00786
00787
00788
00789 if (fflag == 1) {
00790 bptr->outptr--;
00791 bptr->outcnt++;
00792 }
00793 fflag = 1;
00794 }
00795 bptr->f_lbufptr = bptr->f_lbuf;
00796
00797 _memwcpy(bptr->outptr, bptr->f_lbufptr,
00798 bptr->f_lbufcnt);
00799
00800 bptr->outptr += bptr->f_lbufcnt;
00801 bptr->outcnt -= bptr->f_lbufcnt;
00802 bptr->f_lbufptr = bptr->f_lbuf;
00803 bptr->f_lbufcnt = 0;
00804 }
00805 }
00806
00807 *bptr->f_lbufptr++ = (long) '\'';
00808 bptr->f_lbufcnt++;
00809
00810 LPUT(OUT_SEP);
00811 LPUT(' ');
00812 LPUT(' ');
00813
00814 bptr->lcomma = 1;
00815
00816 if (bptr->outcnt <= bptr->f_lbufcnt) {
00817
00818
00819
00820
00821 REPFLUSH();
00822
00823
00824 if (fflag == 1) {
00825 bptr->outptr--;
00826 bptr->outcnt++;
00827 }
00828 }
00829
00830 bptr->f_lbufptr = bptr->f_lbuf;
00831
00832 _memwcpy(bptr->outptr, bptr->f_lbufptr, bptr->f_lbufcnt);
00833
00834 bptr->outptr += bptr->f_lbufcnt;
00835 bptr->outcnt -= bptr->f_lbufcnt;
00836 bptr->f_lbufptr = bptr->f_lbuf;
00837 bptr->f_lbufcnt = 0;
00838
00839 return(0);
00840
00841 ret:
00842 return(ss);
00843 }
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861 int
00862 _wnl_beautify(
00863 ftype_t typ90,
00864 long *ugly,
00865 long *p_limit,
00866 long *pretty,
00867 unsigned isf90)
00868
00869 {
00870 int ret;
00871
00872 ret = _beautify(typ90, ugly, p_limit, pretty, isf90);
00873
00874
00875
00876
00877
00878 if (YMP80 && !isf90 && typ90 == DVTYPE_REAL || typ90 == DVTYPE_COMPLEX){
00879 if (pretty[ret - 1] == '.')
00880 pretty[ret++] = '0';
00881 }
00882
00883 return (ret);
00884 }