Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
rdfmt.c
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001, Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2.1 of the GNU Lesser General Public License 
00007   as published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU Lesser General Public 
00021   License along with this program; if not, write the Free Software 
00022   Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
00023   USA.
00024 
00025   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00026   Mountain View, CA 94043, or:
00027 
00028   http://www.sgi.com
00029 
00030   For further information regarding this notice, see:
00031 
00032   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00033 
00034 */
00035 
00036 
00037 
00038 #pragma ident "@(#) libf/fio/rdfmt.c    92.6    06/21/99 10:37:55"
00039 
00040 #include <memory.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 #include <fortran.h>
00044 #include <cray/fmtconv.h>
00045 #include <cray/format.h>
00046 #include <cray/nassert.h>
00047 #ifdef  _CRAYT3D
00048 #include <cray/mppsdd.h>
00049 #define MAXSH           512
00050 #else
00051 #define MAXSH           1
00052 #endif
00053 #include "fio.h"
00054 #include "fmt.h"
00055 #include "f90io.h"
00056 #include "lio.h"
00057 
00058 extern  const ic_func   *_iconvtab[LAST_DATA_ED + 1];
00059 extern  const short     _idedtab[DVTYPE_NTYPES];
00060 
00061 /*
00062  *      _rdfmt()        Read format processing
00063  *
00064  *              css     Current Fortran I/O statement state pointer
00065  *              cup     Unit pointer
00066  *              dptr    Pointer to data 
00067  *              tip     Type information packet
00068  *
00069  *      Return value
00070  *
00071  *              0               normal return.
00072  *
00073  *              FEEORCND        if end of record condition and IOSTAT= or  
00074  *                              EOR= is specified.
00075  *
00076  *              other <0        if end of file condition and IOSTAT= or  
00077  *                              END= is specified.
00078  *
00079  *              >0              if error condition and IOSTAT= or ERR= is
00080  *                              specified.
00081  */
00082 int
00083 _rdfmt(
00084         FIOSPTR         css,    /* Current Fortran I/O statement state */
00085         unit            *cup,   /* Unit pointer */
00086         void            *dptr,  /* Pointer to data */
00087         type_packet     *tip,   /* Type information packet */
00088         int             _Unused /* Unused by this routine */
00089 )
00090 {
00091         register short  cswitch;        /* 1 if complex data; else zero */
00092         register short  fmtop;          /* Current format operator */
00093         register short  part;           /* Part of datum (complex is 2-part) */
00094         register ftype_t type;          /* Fortran data type */
00095         register int32  chxfer;         /* Chars xferred by data edit descriptors */
00096         register int32  delta;          /* Length/field width difference */
00097         register int32  field;          /* Consecutive conversion field size */
00098         register int32  i;              /* Scratch loop variable */
00099         register int32  itemch;         /* Number of chars available for item */
00100         register int32  kount;          /* Number of consecutive conversions */
00101         register int32  length;         /* Length of datum in bytes */
00102         register int32  padcnt;         /* Number of pad bytes at end of item */
00103         register int32  repcnt;         /* Copy of *css->u.fmt.u.fe.pftocs */
00104         int             cinc[2];        /* Increments for datum parts */
00105         register int    stat;           /* Error code */
00106         register int    stride;         /* Stride between data in bytes */
00107         register char   *cptr;          /* Character pointer to datum */
00108         register char   *ctmp;          /* Temporary character pointer */
00109         long            digits;         /* Digits field of edit-descriptor */
00110         long            mode;           /* Mode word for conversion */
00111         long            *tptr;          /* Temporary line buffer pointer */
00112         long            width;          /* Width field of edit-descriptor */
00113         register long   count;          /* Number of data items */
00114         register long   dfmode;         /* MODEBZ or MODEBN mode bits */
00115         fmt_type        pfmt;           /* Current parsed format entry */
00116 #ifdef  _CRAYT3D
00117         register short  shared;         /* Is variable shared? */
00118         register int    elwords;        /* Number of words per item */
00119         register int    offset;         /* Offset from address in item units */
00120         register int32  tcount;         /* Number of items to move */
00121         long            shrd[MAXSH];    /* Buffer for shared data */
00122 #endif
00123 
00124         int     _nicverr(       /* Map NICV-type errors to Fortran errors */
00125                         const int _Nicverror);
00126 
00127         const ic_func   *ngcf;          /* Generic NICV-type conversion func */
00128 
00129         /* If these assertions are not all true, then we're in deep doo-doo. */
00130 
00131         assert (cup != NULL);
00132         assert (tip != NULL);
00133 
00134         type    = tip->type90;
00135         count   = tip->count;
00136 
00137         chxfer  = 0;
00138         cswitch = 0;
00139         stat    = 0;
00140         part    = 1;
00141 
00142         pfmt    = *css->u.fmt.u.fe.pfcp;
00143         repcnt  = *css->u.fmt.u.fe.pftocs;
00144         length  = tip->elsize;
00145         stride  = tip->stride * length;
00146         cinc[1] = stride;
00147 
00148         /* If COMPLEX data type, set data length and increments */
00149 
00150         if (type == DVTYPE_COMPLEX) {
00151                 length  = length / 2;
00152                 cinc[0] = length;
00153                 cinc[1] = stride - length;
00154                 cswitch = 1;
00155                 part    = 0;
00156         }
00157 
00158         dfmode  = ((css->u.fmt.blank0 == 1) ? MODEBZ : MODEBN);
00159 
00160 #ifdef  _CRAYT3D
00161         if (_issddptr(dptr)) {  /* shared variable */
00162                 offset  = 0;
00163                 elwords = tip->elsize / sizeof(long);
00164                 shared  = 1;
00165                 stride  = tip->elsize;  
00166                 tcount  = count;
00167                 css->f_shrdput  = 1;
00168         }
00169         else
00170                 shared  = 0;
00171 
00172    do   {
00173         if (shared) {   /* shared variable */
00174                 /*
00175                  * We read the data into local array shrd and later 
00176                  * distribute it to shared memory.  We assume for now that
00177                  * shared data never has a container size smaller than a word.
00178                  */
00179                 count   = MIN (MAXSH / elwords, (tcount - offset));     
00180                 cptr    = (char *) shrd;
00181         }
00182         else 
00183 #endif
00184         {
00185                 cptr    = (char *) dptr;
00186         }
00187 
00188         do {    /*  M A I N   L O O P  */
00189 
00190                 fmtop   = pfmt.op_code;         /* Get operator */
00191                 width   = pfmt.field_width;     /* And main parameter */
00192                 digits  = pfmt.digits_field;    /* And secondary parameter */
00193 
00194                 /* Basic sanity check on the parsed format */
00195 
00196                 if (fmtop > LAST_OP || fmtop < FIRST_DATA_ED) {
00197                         stat    = FEINTIPF;     /* Invalid parsed format */
00198                         goto done;
00199                 }
00200 
00201                 if (fmtop <= LAST_DATA_ED) {
00202 
00203                         /*
00204                          * We have a data edit-descriptor and if the count
00205                          * is exhausted, then we're done for now.
00206                          */
00207 
00208                         if (count == 0)
00209                                 goto done;
00210 
00211                         /*
00212                          * Validate the data edit-descriptor against the
00213                          * data type and do the Fortran 90 mapping of the
00214                          * G data edit-descriptor.
00215                          */
00216 
00217                         if (INVALID_RTYPE(fmtop, type)) {
00218                                 stat    = FERDTYPE; /* Type mismatch */
00219                                 goto done;
00220                         }
00221 
00222                         if (fmtop == G_ED) {
00223 
00224                                 fmtop   = _idedtab[type];
00225 
00226                                 if (type != DVTYPE_REAL &&
00227                                     type != DVTYPE_COMPLEX)
00228                                         digits  = 1;
00229                         }
00230 
00231                         if (type == DVTYPE_ASCII) 
00232                                 mode    = 0;
00233                         else {
00234                                 mode    = (long) _rd_ilchk[fmtop-1][length-1];
00235 
00236                                 if (mode == INVALID_INTLEN) {
00237                                         stat    = FERDTYPE; /* Type mismatch */
00238                                         goto done;
00239                                 }
00240                         }
00241 
00242                         mode    = mode | dfmode;
00243 
00244                         /*
00245                          * Handle zero-width formats.
00246                          */
00247 
00248                         if (width == 0) {
00249                                 register int    exp;
00250 
00251                                 switch (fmtop) {
00252 
00253                                 /*
00254                                  * For character (A/R) data edit-
00255                                  * descriptors, the width is the
00256                                  * length of the datum.
00257                                  */
00258                                 case A_ED:
00259                                 case R_ED:
00260                                         width   = length;
00261                                         break;
00262 
00263                                 /*
00264                                  * For integer (B/I/O/Z) data edit-descriptors,
00265                                  * the width is the maximum number of "digits"
00266                                  * plus one for a leading blank and (I only)
00267                                  * one for an optional sign.
00268                                  */
00269                                 case B_ED:
00270                                 case I_ED:
00271                                 case O_ED:
00272                                 case Z_ED:
00273                                         width   = _rw_mxdgt[fmtop-1][length-1];
00274 
00275                                         /* Fix limitation in table */
00276 
00277                                         if (width == 127)
00278                                                 width   = 128;
00279 
00280                                         /* Allow for blank and sign */
00281 
00282                                         width   = width + 1;
00283 
00284                                         if (fmtop == I_ED)
00285                                                 width   = width + 1;
00286 
00287                                         if (pfmt.default_digits)
00288                                                 digits  = 1;
00289                                         break;
00290 
00291                                 /*
00292                                  * For floating-point (D/E/EN/ES/F/G) data
00293                                  * edit-descriptors, the width is the number
00294                                  * of significant digits plus the maximum
00295                                  * size of the exponent plus six (for a
00296                                  * leading blank, an optional sign, an
00297                                  * optional leading zero, a decimal point,
00298                                  * the 'E' exponent designator, and the
00299                                  * exponent sign).
00300                                  */
00301                                 case D_ED:
00302                                 case E_ED:
00303                                 case EN_ED:
00304                                 case ES_ED:
00305                                 case F_ED:
00306                                 case G_ED:
00307                                         if (pfmt.default_digits)
00308                                                 digits  = _rw_mxdgt[fmtop-1][length-1];
00309 
00310                                         if (length == 16)
00311                                                 exp     = DEXP16;
00312 #ifdef  _F_REAL4
00313                                         else if (length == 4)
00314                                                 exp     = DEXP4;
00315 #endif
00316                                         else
00317                                                 exp     = DEXP8;
00318 
00319                                         width   = digits + exp + 6;
00320                                         break;
00321 
00322                                 /*
00323                                  * For logical (L) data edit-descriptors,
00324                                  * the width is always two (one for the 'T'
00325                                  * or 'F' and the other for a leading blank).
00326                                  */
00327                                 case L_ED:
00328                                         width   = _rw_mxdgt[fmtop-1][length-1];
00329                                         break;
00330 
00331                                 /*
00332                                  * For Q data edit-descriptors, the
00333                                  * width is zero--no data is consumed.
00334                                  */
00335                                 case Q_ED:
00336                                         width   = 0;
00337                                         break;
00338 
00339                                 /*
00340                                  * Should never arrive here.
00341                                  */
00342                                 default:
00343                                         width   = -1;
00344                                         break;
00345                                 } /* switch */
00346 
00347                                 /*
00348                                  * Sanity check for valid width.
00349                                  */
00350                                 if (width < 0) {
00351                                         stat    = FERDTYPE; /* Type mismatch */
00352                                         goto done;
00353                                 }
00354                         }
00355 
00356                         /*
00357                          * Check end-of-file and end-of-record conditions.
00358                          */
00359 
00360                         if (cup->uend) {                /* If at EOF */
00361                                 stat    = FERDPEOF;     /* Read past EOF */
00362                                 goto done;
00363                         }
00364 
00365                         /*
00366                          * Set the number of consecutive data items, and be
00367                          * sure to adjust for the case when we're in the middle
00368                          * of a complex datum.
00369                          */
00370 
00371                         kount   = MIN(repcnt,
00372                                   ((count << cswitch) - (part & cswitch)));
00373                         field   = width * kount;
00374 
00375                         /*
00376                          * See if processing the current batch of edit-
00377                          * descriptors will exhaust the record.  If so,
00378                          * see if there's room for one more.
00379                          */
00380 
00381                         if (field > cup->ulinecnt) {
00382 
00383                                 field   = width;
00384                                 kount   = 1;
00385 
00386                                 if (width > cup->ulinecnt) {
00387 
00388                                         /*
00389                                          * If ADVANCE='NO' and the current
00390                                          * edit descriptor requires data from
00391                                          * beyond end of record, we have an
00392                                          * EOR condition.  However, the EOR
00393                                          * condition may be superseded by an
00394                                          * error during data input conversion.  
00395                                          */
00396 
00397                                         if (css->u.fmt.nonadv)
00398                                                 stat    = FEEORCND;
00399                                         else
00400                                                 if (cup->upad == OS_NO)
00401                                                         stat    = FERDPEOR;
00402 
00403                                         /*
00404                                          * If there are no characters left in
00405                                          * the record and PAD='NO', then bypass
00406                                          * the data transfer altogether.
00407                                          */
00408 
00409                                         if (cup->ulinecnt <= 0 &&
00410                                             cup->upad == OS_NO)
00411                                                 goto done;
00412                                 }
00413                         }
00414                 }
00415 
00416                 switch (fmtop) {
00417 
00418                 /* Process numeric input */
00419 
00420                 case B_ED:
00421                 case D_ED:
00422                 case E_ED:
00423                 case EN_ED:
00424                 case ES_ED:
00425                 case F_ED:
00426                 case G_ED:
00427                 case I_ED:
00428                 case L_ED:
00429                 case O_ED:
00430                 case Z_ED:
00431 
00432                         ngcf    = _iconvtab[fmtop];
00433 
00434 #ifdef  _CRAY
00435 #pragma _CRI align
00436 #endif
00437 
00438                         for (i = 0; i < kount; i++) {   /* For consecutive items */
00439                                 register short  j;
00440                                 long            nstat;
00441 
00442                                 /* Clear subsequent words of a multi-word item */
00443 
00444                                 if (length > sizeof(int))
00445                                         for (j = 1; j < (length/sizeof(int)); j++)
00446                                                 ((int *) cptr)[j]       = 0;
00447 
00448                                 itemch  = MIN(MAX(0, cup->ulinecnt), width);
00449                                 tptr    = cup->ulineptr + itemch; /* end of field */
00450                                 nstat   = -1;
00451 
00452                                 (void) ngcf(cup->ulineptr, &width, &tptr, &mode,
00453                                         cptr, &nstat, &digits,
00454                                         &css->u.fmt.u.fe.scale);
00455 
00456                                 if (nstat < 0) {
00457                                         stat    = _nicverr(nstat);
00458                                         if (stat > 0)
00459                                                 goto done;
00460                                 }
00461 
00462                                 /* Advance data addresses */
00463 
00464                                 cup->ulineptr   = cup->ulineptr + itemch;
00465                                 cup->ulinecnt   = cup->ulinecnt - itemch;
00466                                 chxfer          = chxfer + itemch;
00467                                 count           = count - part;
00468                                 cptr            = cptr + cinc[part];
00469                                 part            = part ^ cswitch;
00470                         }
00471 
00472                         repcnt  = repcnt - kount;
00473 
00474                         break;
00475 
00476                 /* Process nonnumeric (character) input */
00477 
00478                 case A_ED:
00479                 case R_ED:
00480 
00481                         delta   = length - width;
00482 
00483                         /*
00484                          * Check if format width equals data length and we have
00485                          * a stride of one.  If so, then we can move all of the
00486                          * data in one fell swoop.
00487                          */
00488 
00489                         if (delta == 0 && tip->stride == 1 && cswitch == 0) {
00490 
00491                                 itemch  = MIN(MAX(0, cup->ulinecnt), field);
00492 
00493                                 (void) _pack(cup->ulineptr, cptr, itemch, -1);
00494 
00495                                 padcnt  = field - itemch;
00496 
00497                                 if (padcnt > 0) /* If variable wider than field */
00498                                         (void) memset(cptr + itemch, BLANK, (size_t) padcnt);
00499 
00500                                 cup->ulineptr   = cup->ulineptr + itemch;
00501                                 cup->ulinecnt   = cup->ulinecnt - itemch;
00502                                 chxfer          = chxfer + itemch;
00503                                 count           = count - kount;
00504                                 cptr            = cptr + (stride * kount);
00505                         }
00506                         else
00507 
00508 #ifdef  _CRAY
00509 #pragma _CRI align
00510 #endif
00511 
00512                         for (i = 0; i < kount; i++) {   /* For consecutive items */
00513 
00514                                 ctmp    = cptr;
00515                                 itemch  = MIN(MAX(0, cup->ulinecnt), width);
00516 
00517                                 /*
00518                                  * If the field width is wider than the length
00519                                  * of the variable, we need to skip over part
00520                                  * of the field.  However, make sure we don't
00521                                  * skip past the end of the record.
00522                                  */
00523 
00524                                 if (delta < 0) { /* If field wider than variable */
00525                                         itemch          = itemch + delta;
00526                                         cup->ulinecnt   = cup->ulinecnt + delta;
00527                                         cup->ulineptr   = cup->ulineptr - delta;
00528                                         padcnt          = (delta + width) - itemch;
00529                                 }
00530 
00531                                 /*
00532                                  * If doing R format and the variable is larger
00533                                  * than the field, we need to right-justify the
00534                                  * data and fill-in the unused portion (we fill
00535                                  * with blanks for character variables and zeros
00536                                  * for all other data types).
00537                                  */
00538 
00539                                 else {
00540                                         padcnt  = delta + (width - itemch);
00541 
00542                                         if (fmtop == R_ED && delta > 0) {
00543                                                 register int    fill;
00544 
00545                                                 fill    = (type == DVTYPE_ASCII) ?
00546                                                                 BLANK : 0;
00547 
00548                                                 (void) memset(ctmp, fill, (size_t) delta);
00549 
00550                                                 ctmp    = ctmp + delta;
00551                                                 padcnt  = padcnt - delta;
00552                                         }
00553                                 }
00554 
00555                                 /* Move the actual data */
00556 
00557                                 if (itemch > 0)
00558                                         (void) _pack(cup->ulineptr, ctmp, itemch, -1);
00559 
00560                                 /*
00561                                  * If the variable is wider than the field, or if there
00562                                  * was insufficient data to satisfy the width, then pad
00563                                  * out the variable with blanks.
00564                                  */
00565 
00566                                 if (padcnt > 0)
00567                                         (void) memset(ctmp + itemch, BLANK, (size_t) padcnt);
00568 
00569                                 /* Advance data addresses */
00570 
00571                                 cup->ulineptr   = cup->ulineptr + itemch;
00572                                 cup->ulinecnt   = cup->ulinecnt - itemch;
00573                                 chxfer          = chxfer + itemch;
00574                                 count           = count - part;
00575                                 cptr            = cptr + cinc[part];
00576                                 part            = part ^ cswitch;
00577                         }
00578 
00579                         repcnt  = repcnt - kount;
00580                         break;
00581 
00582                 case Q_ED:
00583                         if (length == 4)
00584                                 *(_f_int4 *)cptr        = MAX(cup->ulinecnt, 0);
00585                         else if (length == 8)
00586                                 *(_f_int8 *)cptr        = MAX(cup->ulinecnt, 0);
00587                         else if (length == 2)
00588                                 *(_f_int2 *)cptr        = MAX(cup->ulinecnt, 0);
00589                         else    /* Assume length == 1 */
00590                                 *(_f_int1 *)cptr        = MAX(cup->ulinecnt, 0);
00591 
00592                         /* Advance data addresses */
00593 
00594                         count           = count - part;
00595                         cptr            = cptr + cinc[part];
00596                         part            = part ^ cswitch;
00597                         repcnt          = repcnt - 1;
00598                         break;
00599 
00600                 case SLASH_ED:
00601                         stat            = (*css->u.fmt.endrec)(css, cup, width);
00602                         repcnt          = repcnt - 1;
00603                         break;
00604 
00605                 case TR_ED:
00606                         cup->ulineptr   = cup->ulineptr + width;
00607                         cup->ulinecnt   = cup->ulinecnt - width;
00608                         repcnt          = repcnt - 1;
00609                         break;
00610 
00611                 case T_ED:
00612                         tptr            = cup->ulineptr;        /* Old pos. */
00613                         cup->ulineptr   = css->u.fmt.leftablim + width - 1;
00614                         cup->ulinecnt   = cup->ulinecnt + (tptr - cup->ulineptr);
00615                         repcnt          = 0;    /* Ignore repeat count */
00616                         break;
00617 
00618                 case TL_ED:
00619                         cup->ulineptr   = cup->ulineptr - width;
00620                         cup->ulinecnt   = cup->ulinecnt + width;
00621                         /*
00622                          * If tabbed off the beginning of the record,
00623                          * move back to column 1.
00624                          */
00625                         if (cup->ulineptr < css->u.fmt.leftablim) {
00626                                 cup->ulinecnt   = cup->ulinecnt -
00627                                                 (css->u.fmt.leftablim - cup->ulineptr);
00628                                 cup->ulineptr   = css->u.fmt.leftablim;
00629                         }
00630                         repcnt          = repcnt - 1;
00631                         break;
00632 
00633                 case STRING_ED:
00634                         /*
00635                          * Literals and H edit-descriptors are invalid in
00636                          * input formats.
00637                          */
00638                         stat                    = FEFMTLII;
00639                         repcnt                  = repcnt - 1;
00640                         break;
00641 
00642                 case BN_ED:
00643                         css->u.fmt.blank0       = 0;
00644                         dfmode                  = dfmode & ~MODEBZ;
00645                         dfmode                  = dfmode | MODEBN;
00646                         repcnt                  = 0;  /* Ignore repeat count */
00647                         break;
00648 
00649                 case BZ_ED:
00650                         css->u.fmt.blank0       = 1;
00651                         dfmode                  = dfmode & ~MODEBN;
00652                         dfmode                  = dfmode | MODEBZ;
00653                         repcnt                  = 0;  /* Ignore repeat count */
00654                         break;
00655 
00656                 case DOLLAR_ED:         /* $ has no effect on input */
00657                 case S_ED:              /* S, SS, SP have no effect on input */
00658                 case SS_ED:
00659                 case SP_ED:
00660                         repcnt                  = 0;  /* Ignore repeat count */
00661                         break;
00662 
00663                 case P_ED:
00664                         css->u.fmt.u.fe.scale   = pfmt.rep_count;
00665                         repcnt                  = 0;  /* Force advancement */
00666                         break;
00667 
00668                 case COLON_ED:
00669                         /*
00670                          * We have a colon edit-descriptor and, if the count
00671                          * is zero, we're done for now.
00672                          */
00673                         if (count == 0)
00674                                 goto done;
00675 
00676                         repcnt  = 0;    /* Ignore repeat count */
00677                         break;
00678 
00679                 case REPEAT_OP:
00680                         /*
00681                          * Start of repeated format group.  Stack the repeat
00682                          * count and advance to the next format token.
00683                          */
00684                         *css->u.fmt.u.fe.pftocs++       = pfmt.rep_count;
00685                         repcnt                          = 0; /* Force advance*/
00686                         break;
00687 
00688                 case ENDREP_OP:
00689                         /*
00690                          * End of repeated format group.  Decrement the
00691                          * stacked count.  If the repeat count has not
00692                          * been satisfied then proceed to the first format
00693                          * token of the repeat group; otherwise unstack
00694                          * the repeat count and advance to the next format
00695                          * token.
00696                          */
00697                         if ( --(*(css->u.fmt.u.fe.pftocs - 1)) < 1)
00698                                 css->u.fmt.u.fe.pftocs--; /* Pop the rep cnt */
00699                         else
00700                                 css->u.fmt.u.fe.pfcp    = css->u.fmt.u.fe.pfcp +
00701                                                           pfmt.rep_count;
00702 
00703                         repcnt  = repcnt - 1;
00704 
00705                         break;
00706 
00707                 case REVERT_OP:
00708                         /*
00709                          * If the revert group does not contain any data
00710                          * edit-descriptors and iolist items remain
00711                          * (defined as a nonzero count), then we have an
00712                          * infinite format loop.
00713                          */
00714                         if (pfmt.rgcdedf == 0 && count > 0)
00715                                 stat    = FEFMTILF; /* Infinite format loop */
00716                         else {
00717                                 /*
00718                                  * If the count is zero, then we exit with
00719                                  * the format positioned at the REVERT_OP
00720                                  * entry and subsequent calls can continue
00721                                  * from there, if necessary.  If there are
00722                                  * data items remaining (count > 0) then
00723                                  * we flush the record, position the format
00724                                  * to the reversion point, and continue
00725                                  * processing.
00726                                  */
00727 
00728                                 if (count == 0)
00729                                         goto done;
00730 
00731                                 /* Read the next record */
00732 
00733                                 stat    = (*css->u.fmt.endrec)(css, cup, 1);
00734                                 repcnt  = 0;  /* Force advancement */
00735 
00736                                 /* Position format to reversion point */
00737 
00738                                 css->u.fmt.u.fe.pfcp    = css->u.fmt.u.fe.pfcp +
00739                                                           pfmt.rep_count - 1;
00740                         }
00741                         break;
00742 
00743                 default:
00744                         stat    = FEINTIPF;     /* Invalid parsed format */
00745                         break;
00746 
00747                 } /* switch (fmtop) */
00748 
00749                 /*
00750                  * If the repeat count has been exhausted then advance to
00751                  * the next format token.
00752                  */
00753 
00754                 if (stat == 0 && repcnt < 1) {
00755 
00756                         if (fmtop == STRING_ED)
00757                                 css->u.fmt.u.fe.pfcp    = css->u.fmt.u.fe.pfcp +
00758                                                  ((width +
00759                                                   FMT_ENTRY_BYTE_SIZE - 1) /
00760                                                   FMT_ENTRY_BYTE_SIZE);
00761 
00762                         css->u.fmt.u.fe.pfcp    = css->u.fmt.u.fe.pfcp + 1;
00763                         pfmt            = *css->u.fmt.u.fe.pfcp;
00764                         repcnt          = pfmt.rep_count;
00765                         css->u.fmt.u.fe.fmtcol  = pfmt.offset; /* New position*/
00766                 }
00767 
00768         } while (stat == 0);
00769 done:
00770 
00771 #ifdef  _CRAYT3D
00772         if (shared && ((long *) cptr != shrd)) {
00773                 register int    items;
00774 
00775                 /* Move the data to shared memory, see if there is more to do */
00776 
00777                 items   = ((long *) cptr - shrd) / elwords;
00778                 (void) _cpytosdd(dptr, shrd, items, elwords, tip->stride, offset);
00779                 offset  = offset + items;
00780         }
00781 
00782    } while (stat == 0 && shared && offset < tcount);
00783 #endif
00784 
00785         /* Update unit table and statement state fields */
00786 
00787         *css->u.fmt.u.fe.pftocs = repcnt;
00788 
00789         if (css->u.fmt.nonadv)  /* Increment the SIZE value */
00790                 css->u.fmt.u.fe.charcnt = css->u.fmt.u.fe.charcnt + chxfer;
00791 
00792         /* Process any error which occurred */
00793 
00794         if (stat == FEEORCND) {
00795                 if ((cup->uflag & (_UEORF | _UIOSTF)) == 0)
00796                         _ferr(css, stat);       /* end of record condition */
00797 
00798                 cup->pnonadv    = 0;            /* flag no more current rec */ 
00799         }
00800         else if (stat > 0) {
00801                 if ((cup->uflag & (_UERRF | _UIOSTF)) == 0)
00802                         _ferr(css, stat);       /* Run-time error */
00803         }
00804         else if (stat < 0) {
00805                  if ((cup->uflag & (_UENDF | _UIOSTF)) == 0)
00806                         _ferr(css, stat);       /* EOF-type error */
00807         }
00808 
00809         return(stat);
00810 }
00811 
00812 #if     defined(__mips) || (defined(_LITTLE_ENDIAN) && defined(__sv2))
00813 #include <ieeefp.h>
00814 #elif   defined(_LITTLE_ENDIAN) && !(__sv2)
00815 #include <fpu_control.h>
00816 #endif
00817 /*
00818  *      _nicverr()  Map NICV-type errors to Fortran error codes.
00819  *    
00820  *      On mips with overflow and underflow, allow the return of zero
00821  *      or infinity if the csr is off for these two interrupts.  The
00822  *      conversion routines return the correct value but also return
00823  *      a negative value to indicate overflow or underflow.  Return a
00824  *      zero as the function result if the error is not to be given.
00825  *    
00826  */
00827 int
00828 _nicverr(const int nicverror)
00829 {
00830         int     errn;
00831 
00832         switch (nicverror) {
00833                 case EX_ILLCHAR:        /* Invalid (nonnumeric) character */
00834                         errn    = FENICVIC;
00835                         break;
00836                 case EX_FIXOFLO:        /* Fixed-point overflow */
00837                         errn    = FENICVOF;
00838                         break;
00839                 case EX_EXPUFLO:        /* Floating-point underflow */
00840                         errn    = FENICVEU;
00841 #if     defined(__mips) || (defined(_LITTLE_ENDIAN) && defined(__sv2))
00842                         /* this returns only the mask bits */
00843                         if ((fpgetmask() & FP_X_UFL) == 0)
00844                                 errn    = 0;
00845 #elif   defined (_LITTLE_ENDIAN) && !defined(__sv2)
00846 #endif
00847                         break;
00848                 case EX_EXPOFLO:        /* Floating-point overflow */
00849                         errn    = FENICVEO;
00850 #if     defined(__mips) || (defined(_LITTLE_ENDIAN) && defined(__sv2))
00851                         /* this returns only the mask bits */
00852                         if ((fpgetmask() & FP_X_OFL) == 0)
00853                                 errn    = 0;
00854 #elif   defined (_LITTLE_ENDIAN) && !defined(__sv2)
00855 #endif
00856                         break;
00857                 case EX_NULLFLD:        /* Null field */
00858                         errn    = FENICVBK;
00859                         break;
00860                 case EX_INVLOGI:        /* Invalid logical input */
00861                         errn    = FERDIVLG;
00862                         break;
00863                 default:        /* Unknown (internal) error */
00864                         errn    = FEINTUNK;
00865                         break;
00866         }
00867 
00868         return(errn);
00869 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines