Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
wrfmt.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/wrfmt.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 oc_func   *_oconvtab[LAST_DATA_ED + 1];
00059 extern  const short     _odedtab[DVTYPE_NTYPES];
00060 extern  short           _o_sup_flg_tab[DVTYPE_NTYPES];
00061 extern  long            _o_sup_val_tab[DVTYPE_NTYPES];
00062 
00063 #undef  BLANK
00064 #define BLANK   ((long) ' ')
00065 
00066 /*
00067  *      _wrfmt()        Write format processing
00068  *
00069  *              uss     Current Fortran I/O statement state pointer
00070  *              cup     Unit pointer
00071  *              dptr    Pointer to data 
00072  *              tip     Type information packet
00073  */
00074 int
00075 _wrfmt(
00076         FIOSPTR         css,    /* Current Fortran I/O statement state */
00077         unit            *cup,   /* Unit pointer */
00078         void            *dptr,  /* Pointer to data */
00079         type_packet     *tip,   /* Type information packet */
00080         int             _Unused /* Unused by this routine */
00081 )
00082 {
00083         register short  cswitch;        /* 1 if complex data; else zero */
00084         register short  fmtop;          /* Current format operator */
00085         register short  part;           /* Part of datum (complex is 2-part) */
00086         register short  supflg;         /* Is variable eligible to be suppressed */
00087         register ftype_t type;          /* Fortran data type */
00088         register int32  delta;          /* Length/field width difference */
00089         register int32  field;          /* Consecutive conversion field size */
00090         register int32  i;              /* Scratch loop variable */
00091         register int32  kount;          /* Number of consecutive conversions */
00092         register int32  length;         /* Length of datum in bytes */
00093         register int32  repcnt;         /* Local copy of *css->u.fmt.pftocs */
00094         int             cinc[2];        /* Increments for datum parts */
00095         register int    stat;           /* Error code */
00096         register int    stride;         /* Stride between data in bytes */
00097         register char   *cptr;          /* Character pointer to datum */
00098         register char   *ctmp;          /* Temporary character pointer */
00099         long            digits;         /* Digits field of edit-descriptor */
00100         long            exp;            /* Exponent field of edit-descriptor */
00101         long            mode;           /* Mode word for conversion */
00102         long            width;          /* Width field of edit-descriptor */
00103         register long   count;          /* Number of data items */
00104         register long   dfmode;         /* MODESN/MODE77 mode bits */
00105         fmt_type        pfmt;           /* Current parsed format entry */
00106 #ifdef  _CRAYT3D
00107         register short  shared;         /* Is variable shared? */
00108         register int    elwords;        /* Number of words per item */
00109         register int    offset;         /* Offset from address in item units */
00110         register int32  tcount;         /* Number of items to move */
00111         long            shrd[MAXSH];    /* Buffer for shared data */
00112 #endif
00113 
00114         const oc_func   *ngcf;          /* Generic NOCV-type conversion func */
00115 
00116         /* If these assertions are not all true, then we're in deep doo-doo */
00117 
00118         assert (cup != NULL);
00119         assert (tip != NULL);
00120 
00121         type    = tip->type90;
00122         count   = tip->count;
00123 
00124         cswitch = 0;
00125         stat    = 0;
00126         part    = 1;
00127 
00128         pfmt    = *css->u.fmt.u.fe.pfcp;
00129         repcnt  = *css->u.fmt.u.fe.pftocs;
00130         length  = tip->elsize;
00131         stride  = tip->stride * length;
00132         cinc[1] = stride;
00133         supflg  = _o_sup_flg_tab[type] && (length == sizeof(long));
00134 
00135         /* If COMPLEX data type, adjust data length and increments */
00136 
00137         if (type == DVTYPE_COMPLEX) {
00138                 length  = length / 2;
00139                 cinc[0] = length;
00140                 cinc[1] = stride - length;
00141                 cswitch = 1;
00142                 part    = 0;
00143         }
00144 
00145         dfmode  = ((cup->uft90 == 0) ? MODE77 : 0) |
00146                   ((css->u.fmt.cplus == 1) ? MODESN : 0);
00147 
00148 #ifdef  _CRAYT3D
00149         if (_issddptr(dptr)) {
00150                 offset  = 0;
00151                 elwords = tip->elsize / sizeof(long);
00152                 shared  = 1;
00153                 stride  = tip->elsize;  
00154                 tcount  = count;
00155         }
00156         else
00157                 shared  = 0;
00158 
00159    do   {
00160         if (shared) {
00161                 /* we copy the data into local array shrd, and write */
00162                 /* from there */
00163                 count   = MIN(MAXSH/elwords, (tcount - offset));
00164                 cptr    = (char *) shrd;
00165 
00166                 (void) _cpyfrmsdd(dptr, shrd, count, elwords, tip->stride, offset);
00167                 offset  = offset + count;
00168         }
00169         else 
00170 #endif
00171         {
00172                 cptr    = (char *) dptr;
00173         }
00174 
00175         do {    /*  M A I N   L O O P  */
00176 
00177                 fmtop   = pfmt.op_code;         /* Get operator */
00178                 width   = pfmt.field_width;     /* And main parameter */
00179                 digits  = pfmt.digits_field;    /* And secondary parameter */
00180                 exp     = pfmt.exponent;
00181 
00182                 /* Basic sanity check on the parsed format */
00183 
00184                 if (fmtop > LAST_OP || fmtop < FIRST_DATA_ED) {
00185                         stat    = FEINTIPF;     /* Invalid parsed format */
00186                         goto done;
00187                 }
00188 
00189                 if (fmtop <= LAST_DATA_ED || fmtop == STRING_ED) {
00190 
00191                         if (fmtop == STRING_ED)
00192 
00193                                 kount   = repcnt;
00194 
00195                         else {  /* fmtop <= LAST_DATA_ED */
00196 
00197                                 /*
00198                                  * We have a data-edit descriptor and if the
00199                                  * count is exhausted, then we're done (for
00200                                  * the time being).
00201                                  */
00202 
00203                                 if (count == 0)
00204                                         goto done;
00205 
00206                                 /*
00207                                  * Validate the data edit-descriptor against
00208                                  * the data type and do the Fortran 90 mapping
00209                                  * G data edit-descriptor.
00210                                  */
00211 
00212                                 if (INVALID_WTYPE(fmtop, type)) {
00213                                         /* Type mismatch */
00214                                         stat    = FEWRTYPE;
00215                                         goto done;
00216                                 }
00217 
00218                                 if (fmtop == G_ED) {
00219 
00220                                         fmtop   = _odedtab[type];
00221 
00222                                         if (type != DVTYPE_REAL &&
00223                                             type != DVTYPE_COMPLEX)
00224                                                 digits  = 1;
00225                                 }
00226 
00227                                 /*
00228                                  * Set (or reset) the default mode for the
00229                                  * numeric conversion routines.
00230                                  */
00231 
00232                                 if (type == DVTYPE_ASCII)
00233                                         mode    = 0;
00234                                 else {
00235                                         mode    = (long) _wr_ilchk[fmtop-1][length-1];
00236 
00237                                         if (mode == INVALID_INTLEN) {
00238                                                 /* Type mismatch */
00239                                                 stat    = FEWRTYPE;
00240                                                 goto done;
00241                                         }
00242                                 }
00243 
00244                                 /* if real and the flag to skip write
00245                                  * of minus sign of -0.0 is set, set
00246                                  * mode bit for conversion routines.
00247                                  */
00248 
00249                                 if ((type == DVTYPE_REAL ||
00250                                      type == DVTYPE_COMPLEX) &&
00251                                      cup->ufnegzero != 0)
00252                                         mode    = mode | MODEMSN;
00253 
00254                                 mode    = mode | dfmode; /* Add defaults */
00255 
00256                                 /*
00257                                  * Handle zero-width formats.
00258                                  */
00259 
00260                                 if (width == 0) {
00261                                         switch (fmtop) {
00262 
00263                                         /*
00264                                          * For character (A/R) data edit-
00265                                          * descriptors, the width is the
00266                                          * length of the datum.
00267                                          */
00268                                         case A_ED:
00269                                         case R_ED:
00270                                                 width   = length;
00271                                                 break;
00272 
00273                                         /*
00274                                          * For integer (B/I/O/Z) data edit-
00275                                          * descriptors, the width is the
00276                                          * maximum number of "digits" plus
00277                                          * one for a leading blank and (I
00278                                          * only) one for an optional sign.
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                                                 /* Fix limitation in table */
00286 
00287                                                 if (width == 127)
00288                                                         width   = 128;
00289 
00290                                                 if (pfmt.default_digits)
00291                                                         digits  = 1;
00292                                                 else if (width < digits)
00293                                                         width   = digits;
00294 
00295                                                 /* Allow for blank and sign */
00296 
00297                                                 width   = width + 1;
00298 
00299                                                 if (fmtop == I_ED)
00300                                                         width   = width + 1;
00301 
00302                                                 /*
00303                                                  * The (f95) standard explicitly
00304                                                  * requires that {B|I|O|Z}0.0
00305                                                  * format with a zero datum
00306                                                  * produce exactly one blank.
00307                                                  * The only practical way to do
00308                                                  * this is to peek at the datum
00309                                                  * now and--if it's zero--adjust
00310                                                  * the field width accordingly.
00311                                                  */
00312 
00313                                                 if (digits == 0) {
00314                                                         register int64  datum;
00315 
00316                                                         switch (length) {
00317 
00318                                                         case 8:
00319                                                                 datum   = *(int64 *) cptr;
00320                                                                 break;
00321 
00322 #ifndef _CRAY1
00323                                                         case 4:
00324                                                                 datum   = *(int32 *) cptr;
00325                                                                 break;
00326 #endif
00327 
00328 #if     defined(__mips) || defined(_SOLARIS) || defined(_LITTLE_ENDIAN)
00329                                                         case 2:
00330                                                                 datum   = *(short *) cptr;
00331                                                                 break;
00332 
00333                                                         case 1:
00334                                                                 datum   = *cptr;
00335                                                                 break;
00336 #endif
00337 
00338                                                         } /* switch */
00339 
00340                                                         if (datum == 0)
00341                                                                 width   = 1;
00342                                                 }
00343                                                 break;
00344 
00345                                         /*
00346                                          * For floating-point (D/E/EN/ES/F/G)
00347                                          * data edit-descriptors, the width
00348                                          * is the number of significant digits
00349                                          * plus the max. size of the exponent
00350                                          * plus six (for a leading blank, an
00351                                          * optional sign, an optional leading
00352                                          * zero, a decimal point, the 'E'
00353                                          * exponent designator, and the
00354                                          * exponent sign).
00355                                          */
00356                                         case D_ED:
00357                                         case E_ED:
00358                                         case EN_ED:
00359                                         case ES_ED:
00360                                         case F_ED:
00361                                         case G_ED:
00362                                                 if (pfmt.default_digits)
00363                                                         digits  = _rw_mxdgt[fmtop-1][length-1];
00364 
00365                                                 if (exp == 0) {
00366                                                         if (length == 16)
00367                                                                 exp     = DEXP16;
00368 #ifdef  _F_REAL4
00369                                                         else if (length == 4)
00370                                                                 exp     = DEXP4;
00371 #endif
00372                                                         else
00373                                                                 exp     = DEXP8;
00374                                                 }
00375 
00376                                                 width   = digits + exp + 6;
00377                                                 break;
00378 
00379                                         /*
00380                                          * For logical (L) data edit-
00381                                          * descriptors, the width is always
00382                                          * two (one for the 'T' or 'F' and
00383                                          * the other for a leading blank).
00384                                          */
00385                                         case L_ED:
00386                                                 width   = _rw_mxdgt[fmtop-1][length-1];
00387                                                 break;
00388 
00389                                         /*
00390                                          * For Q data edit-descriptors, the
00391                                          * width is zero--no data is consumed.
00392                                          */
00393                                         case Q_ED:
00394                                                 width   = 0;
00395                                                 break;
00396 
00397                                         /*
00398                                          * Should never arrive here.
00399                                          */
00400                                         default:
00401                                                 width   = -1;
00402                                                 break;
00403                                         } /* switch */
00404 
00405                                         /*
00406                                          * Sanity check for valid width.
00407                                          */
00408                                         if (width < 0) {
00409                                                 stat    = FEWRTYPE;
00410                                                 goto done;
00411                                         }
00412                                 }
00413 
00414                                 /*
00415                                  * Set the number of consecutive data items, and be
00416                                  * sure to adjust for the case when we're in the
00417                                  * middle of a complex datum.
00418                                  */
00419 
00420                                 kount   = MIN(repcnt,
00421                                           ((count << cswitch) - (part & cswitch)));
00422                         }
00423 
00424                         field   = width * kount;
00425 
00426                         /*
00427                          * Check to see if we have an outstanding TR condition.
00428                          * If so, then blank fill that portion of the record
00429                          * which extends beyond the existing highwater mark
00430                          * (cup->ulinemax); but in no case go beyond the end of
00431                          * the line buffer (cup->urecsize).
00432                          */
00433 
00434                         if (cup->ulinecnt > cup->ulinemax) {
00435                                 register short  j, k;
00436 
00437                                 if (cup->ulinecnt > cup->urecsize) {
00438                                         stat    = FEWRLONG; /* Record too long*/
00439                                         goto done;
00440                                 }
00441 
00442                                 k       = cup->ulinecnt;
00443 
00444                                 /* The following loop should vectorize */
00445 
00446                                 for (j = cup->ulinemax; j < k; j++)
00447                                         cup->ulinebuf[j]        = BLANK;
00448 
00449                                 /* Update highwater mark */
00450 
00451                                 cup->ulinemax   = cup->ulinecnt;
00452                         }
00453 
00454                         /*
00455                          * See if processing the current batch of edit-
00456                          * descriptors will overflow the line.  If so,
00457                          * see if there's room for one more.
00458                          */
00459 
00460                         if ((cup->ulinecnt + field) > cup->urecsize) {
00461 
00462                                 if ((cup->ulinecnt + width) > cup->urecsize) {
00463                                         stat    = FEWRLONG;     /* Record too long */
00464                                         goto done;
00465                                 }
00466                                 else {  /* Do one item */
00467                                         kount   = 1;
00468                                         field   = width;
00469                                 }
00470                         }
00471                 }
00472 
00473                 switch (fmtop) {
00474 
00475                 /* Process numeric-type output */
00476 
00477                 case B_ED:
00478                 case O_ED:
00479                 case Z_ED:
00480                 case D_ED:
00481                 case E_ED:
00482                 case EN_ED:
00483                 case ES_ED:
00484                 case F_ED:
00485                 case G_ED:
00486                 case I_ED:
00487                 case L_ED:
00488 
00489                         ngcf    = _oconvtab[fmtop];
00490 
00491 #ifdef  _CRAY
00492 #pragma _CRI align
00493 #endif
00494 
00495                         for (i = 0; i < kount; i++) { /* For consecutive items */
00496 
00497                                 /* Convert next item */
00498 
00499                                 if (supflg && (_o_sup_val_tab[type] == *(long *) cptr)) {
00500                                         register short  j;
00501 
00502 #ifdef  _CRAY1
00503 #pragma _CRI ivdep
00504 #endif
00505                                         for (j = 0; j < width; j++)
00506                                                 cup->ulineptr[j]        = BLANK;
00507                                 }
00508                                 else
00509                                         (void) ngcf(cptr, cup->ulineptr, &mode,
00510                                                 &width, &digits, &exp,
00511                                                 &css->u.fmt.u.fe.scale);
00512 
00513                                 /* Advance data addresses */
00514 
00515                                 cup->ulineptr   = cup->ulineptr + width;
00516                                 count           = count - part;
00517                                 cptr            = cptr + cinc[part];
00518                                 part            = part ^ cswitch;
00519                         }
00520 
00521                         cup->ulinecnt   = cup->ulinecnt + field;
00522 
00523                         /* Set new highwater mark, if necessary */
00524 
00525                         if (cup->ulinecnt > cup->ulinemax)
00526                                 cup->ulinemax   = cup->ulinecnt;
00527 
00528                         repcnt  = repcnt - kount;
00529 
00530                         break;
00531 
00532                 /* Process nonnumeric (character) output */
00533 
00534                 case A_ED:
00535                 case R_ED:
00536 
00537                         delta   = width - length;
00538 
00539                         /*
00540                          * Check if format width equals data length and we have
00541                          * a stride of one.  If so, then we can move all of the
00542                          * data in one fell swoop.
00543                          */
00544 
00545                         if (delta == 0 && tip->stride == 1) {
00546                                 register short  knt;
00547 
00548                                 (void) _unpack(cptr, cup->ulineptr, field, -1);
00549 
00550                                 cup->ulineptr   = cup->ulineptr + field;
00551                                 knt             = kount >> cswitch;
00552 
00553                                 if (cswitch != 0 && ((kount & 01) != 0)) {
00554 
00555                                         /* If complex and odd count */
00556 
00557                                         count   = count - part;
00558                                         cptr    = cptr + cinc[part];
00559                                         part    = part ^ 1;
00560                                 }
00561 
00562                                 count   = count - knt;
00563                                 cptr    = cptr + (stride * knt);
00564                         }
00565                         else
00566 
00567 #ifdef  _CRAY
00568 #pragma _CRI align
00569 #endif
00570 
00571                         for (i = 0; i < kount; i++) {   /* For consecutive items */
00572 
00573                                 ctmp    = cptr;
00574 
00575                                 /*
00576                                  * If the field width is wider than the length
00577                                  * of the variable, we need to generate blanks
00578                                  * for part of the field.
00579                                  */
00580 
00581                                 if (delta > 0) {
00582                                         register short  j;
00583 
00584                                         /* The following loop should vectorize */
00585 
00586                                         for (j = 0; j < delta; j++)
00587                                                 cup->ulineptr[j]        = BLANK;
00588 
00589                                         /* Move the actual data */
00590 
00591                                         (void) _unpack(ctmp, cup->ulineptr + delta,
00592                                                 length, -1);
00593                                 }
00594                                 else {
00595 
00596                                         /*
00597                                          * If doing R format and the variable is
00598                                          * larger than the field, we need to
00599                                          * right-justify the data in the field.
00600                                          */
00601 
00602                                         if (fmtop == R_ED)
00603                                                 ctmp    = ctmp - delta;
00604 
00605                                         /* Move the actual data */
00606 
00607                                         (void) _unpack(ctmp, cup->ulineptr, width, -1);
00608                                 }
00609 
00610                                 /* Advance data addresses */
00611 
00612                                 cup->ulineptr   = cup->ulineptr + width;
00613                                 count           = count - part;
00614                                 cptr            = cptr + cinc[part];
00615                                 part            = part ^ cswitch;
00616                         }
00617 
00618                         cup->ulinecnt   = cup->ulinecnt + field;
00619 
00620                         /* Set new highwater mark, if necessary */
00621 
00622                         if (cup->ulinecnt > cup->ulinemax)
00623                                 cup->ulinemax   = cup->ulinecnt;
00624 
00625                         repcnt  = repcnt - kount;
00626 
00627                         break;
00628 
00629                 case SLASH_ED:
00630                         stat    = (*css->u.fmt.endrec)(css, cup, width);
00631                         repcnt  = repcnt - 1;
00632                         break;
00633 
00634                 case TR_ED:
00635                         cup->ulinecnt   = cup->ulinecnt + width;
00636                         cup->ulineptr   = cup->ulineptr + width;
00637                         repcnt          = repcnt - 1;
00638                         break;
00639 
00640                 case T_ED:
00641                         cup->ulinecnt   = width - 1;
00642                         cup->ulineptr   = cup->ulinebuf + (width - 1);
00643                         repcnt          = 1;    /* Ingore repeat count */
00644                         goto check_left;
00645 
00646                 case TL_ED:
00647                         cup->ulinecnt   = cup->ulinecnt - width;
00648                         cup->ulineptr   = cup->ulineptr - width;
00649 check_left:
00650                         /*
00651                          * If tabbed off the beginning of the record, then
00652                          * move back to column 1 (relative to left tab limit).
00653                          */
00654                         if (cup->ulineptr < css->u.fmt.leftablim) {
00655                                 cup->ulineptr   = css->u.fmt.leftablim;
00656                                 cup->ulinecnt   = cup->ulineptr - cup->ulinebuf;
00657                         }
00658 
00659                         repcnt          = repcnt - 1;
00660                         break;
00661 
00662                 case STRING_ED:
00663                         ctmp    = (char *) (css->u.fmt.u.fe.pfcp + 1);
00664 
00665                         if (width > 0) {
00666 
00667                                 /* Copy literal to line buffer */
00668 
00669                                 for (i = 0; i < kount; i++) {
00670 
00671                                         (void) _unpack(ctmp, cup->ulineptr, width, -1);
00672 
00673                                         cup->ulineptr   = cup->ulineptr + width;
00674                                 }
00675 
00676                                 cup->ulinecnt   = cup->ulinecnt + field;
00677 
00678                                 /* Set new highwater mark, if necessary */
00679 
00680                                 if (cup->ulinecnt > cup->ulinemax)
00681                                         cup->ulinemax   = cup->ulinecnt;
00682                         }
00683 
00684                         repcnt  = repcnt - kount;
00685                         break;
00686 
00687                 case BN_ED:             /* BN and BZ have no effect on output */
00688                 case BZ_ED:
00689                         repcnt  = 0;    /* Ignore repeat count */
00690                         break;
00691 
00692                 case S_ED:
00693                 case SS_ED:
00694                         css->u.fmt.cplus        = 0;
00695                         dfmode                  = dfmode & ~MODESN;
00696                         repcnt                  = 0;    /* Ignore repeat count*/
00697                         break;
00698 
00699                 case SP_ED:
00700                         css->u.fmt.cplus        = 1;
00701                         dfmode                  = dfmode | MODESN;
00702                         repcnt                  = 0;    /* Ignore repeat count*/
00703                         break;
00704 
00705                 case P_ED:
00706                         css->u.fmt.u.fe.scale   = pfmt.rep_count;
00707                         repcnt                  = 0;    /* No repeat cnt for P*/
00708                         break;
00709 
00710                 case Q_ED:
00711                         /*
00712                          * The Q edit-descriptor is invalid on output.
00713                          */
00714                         stat                    = FEFMTQIO;
00715                         repcnt                  = repcnt - 1;
00716                         break;
00717 
00718                 case COLON_ED:
00719                         /*
00720                          * We have a colon edit-descriptor and, if the count
00721                          * is zero, we're done for now.
00722                          */
00723 
00724                         if (count == 0)
00725                                 goto done;
00726 
00727                         repcnt          = 0;    /* Ignore repeat count */
00728                         break;
00729 
00730                 case DOLLAR_ED:
00731                         css->u.fmt.nonl = 1;
00732                         repcnt          = 0;    /* Ignore repeat count */
00733                         break;
00734 
00735                 case REPEAT_OP:
00736                         /*
00737                          * Start of repeated format group.  Stack the repeat
00738                          * count and advance to the next format token.
00739                          */
00740                         *css->u.fmt.u.fe.pftocs++       = pfmt.rep_count;
00741                         repcnt                          = 0; /* Force advance */
00742                         break;
00743 
00744                 case ENDREP_OP:
00745                         /*
00746                          * End of repeated format group.  Decrement the
00747                          * stacked count.  If the repeat count has not
00748                          * been satisfied then proceed to the first format
00749                          * token of the repeat group; otherwise unstack
00750                          * the repeat count and advance to the next format
00751                          * token.
00752                          */
00753                         if ( --(*(css->u.fmt.u.fe.pftocs - 1)) < 1)
00754                                 css->u.fmt.u.fe.pftocs--; /* Pop repeat count */
00755                         else
00756                                 css->u.fmt.u.fe.pfcp    = css->u.fmt.u.fe.pfcp +
00757                                                   pfmt.rep_count;
00758                         repcnt  = repcnt - 1;
00759 
00760                         break;
00761 
00762                 case REVERT_OP:
00763                         /*
00764                          * If the revert group does not contain any data
00765                          * edit-descriptors and iolist items remain
00766                          * (defined as a nonzero count), then we have an
00767                          * infinite format loop.
00768                          */
00769                         if (pfmt.rgcdedf == 0 && count > 0)
00770                                 stat    = FEFMTILF; /* Infinite format loop */
00771                         else {
00772                                 /*
00773                                  * If the count is zero, then we exit with
00774                                  * the format positioned at the REVERT_OP
00775                                  * entry and subsequent calls can continue
00776                                  * from there, if necessary.  If there are
00777                                  * data items remaining (count > 0) then
00778                                  * we flush the record, position the format
00779                                  * to the reversion point, and continue
00780                                  * processing.
00781                                  */
00782 
00783                                 if (count == 0)
00784                                         goto done;
00785 
00786                                 /* Write the record */
00787 
00788                                 stat    = (*css->u.fmt.endrec)(css, cup, 1);
00789 
00790                                 repcnt  = 0;    /* Force advancement */
00791 
00792                                 /* Position format to reversion point */
00793 
00794                                 css->u.fmt.u.fe.pfcp    = css->u.fmt.u.fe.pfcp +
00795                                                         pfmt.rep_count - 1;
00796                         }
00797                         break;
00798 
00799                 default:
00800                         stat    = FEINTIPF;     /* Invalid parsed format */
00801                         break;
00802 
00803                 } /* switch (fmtop) */
00804 
00805                 /*
00806                  * If the repeat count has been exhausted then advance to
00807                  * the next format token.
00808                  */
00809 
00810                 if (stat == 0 && repcnt < 1) {
00811 
00812                         if (fmtop == STRING_ED)
00813                                 css->u.fmt.u.fe.pfcp    = css->u.fmt.u.fe.pfcp +
00814                                                  ((width +
00815                                                   FMT_ENTRY_BYTE_SIZE - 1) /
00816                                                   FMT_ENTRY_BYTE_SIZE);
00817 
00818                         css->u.fmt.u.fe.pfcp    = css->u.fmt.u.fe.pfcp + 1;
00819                         pfmt            = *css->u.fmt.u.fe.pfcp;
00820                         fmtop           = pfmt.op_code;
00821                         width           = pfmt.field_width;
00822                         repcnt          = pfmt.rep_count;
00823                         css->u.fmt.u.fe.fmtcol  = pfmt.offset; /* pos in fmt */
00824                 }
00825 
00826         } while (stat == 0);
00827 done:
00828 
00829 #ifdef  _CRAYT3D
00830    continue;
00831    } while (stat == 0 && shared && offset < tcount);
00832 #endif
00833 
00834         /* Update unit table fields */
00835 
00836         *css->u.fmt.u.fe.pftocs = repcnt;
00837 
00838         /* Process any error which occurred */
00839 
00840         if (stat > 0 && (cup->uflag & (_UERRF | _UIOSTF)) == 0)
00841                 _ferr(css, stat);
00842 
00843         return(stat);
00844 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines