Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
lread.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/lread.c    92.3    06/18/99 15:49:57"
00039 
00040 #include <limits.h>
00041 #include <ctype.h>
00042 #include <stdlib.h>
00043 #include <string.h>
00044 #include <fortran.h>
00045 #include <cray/fmtconv.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 "lio.h"
00055 #include "f90io.h"
00056 
00057 /*
00058  *      16-byte real is not currently supported on MPP
00059  */
00060 
00061 #if     defined(_CRAYMPP) || (defined(_ABSOFT) && defined(_LD64))
00062 #if     defined _F_REAL16 && _F_REAL16 == (-1)
00063 #define FAKE_REAL16
00064 #endif
00065 #endif
00066 
00067 /* External functions */
00068 
00069 extern int
00070 _nicverr(const int _Nicverror);
00071 
00072 extern void
00073 _set_stride(void *dest, void *src, long count, int elsize, long inc);
00074 
00075 /*
00076  *      This table is used to drive input conversion based on the type of the
00077  *      data.
00078  */
00079 extern const ic_func    *_ilditab[DVTYPE_NTYPES];
00080 
00081 /*
00082  *      _gen_real is a float (REAL) variable type of largest supported kind.
00083  *
00084  */
00085 
00086 #if     !defined(_F_REAL16) || defined(FAKE_REAL16)
00087 typedef _f_real8        _gen_real;
00088 #else
00089 typedef _f_real16       _gen_real;
00090 #endif
00091 
00092 /* 
00093  *      The repdata structure is used by scanning routines to manage repeated
00094  *      list-directed input data.
00095  */
00096 struct repdata {
00097 
00098         long    repcnt;         /* The remaining repeat count */
00099 
00100         enum reptypes {
00101 
00102                 REPNONE = 0,    /* Indicate no leftover repeat value */
00103                 REPLINE,        /* Get input value from current line
00104                                  * buffer; the value does NOT span lines. */
00105                 REPCHAR,        /* Get character value from packed buffer */
00106                 REPCPLX,        /* Complex value is repeated */
00107                 REPNULL         /* Null value is repeated */
00108 
00109         } reptype;      /* type of repeated data */
00110 
00111         union {
00112 
00113                 struct { /* for REPLINE */
00114                         long    *lptr;  /* Pointer to input field */
00115                         int     lcnt;   /* Characters left in record */
00116                 } line;
00117 
00118                 struct { /* for REPCHAR */
00119                         char    *repchr;/* Pointer to buffer containing a 
00120                                          * packed copy of a repeated input 
00121                                          * quoted character string; NULL
00122                                          * otherwise. */
00123                         long    repsize;/* Number of characters in repeated
00124                                          * value */
00125                 } rchr;
00126 
00127                 struct { /* for REPCPLX */
00128                         _gen_real r[2]; /* Complex value */
00129                 } cplx;
00130         } u;
00131 };
00132 
00133 
00134 /* Forward references for local functions */
00135 
00136 void
00137 _cmplx_convert(void *dest, int size, _gen_real src[2]);
00138 
00139 long
00140 _get_repcount(long *ptr, int limit, long *width);
00141 
00142 int
00143 _get_value( long *lptr, int lcnt, void *ptr, ftype_t type, int elsize,
00144         long *width);
00145 
00146 int
00147 _mr_scan_char(FIOSPTR css, unit *cup, char *ptr, int elsize,
00148         char **chptr, long *slen);
00149 
00150 int
00151 _mr_scan_complex(FIOSPTR css, unit *cup, void *cpxptr, int elsize,
00152         short is_mult);
00153 
00154 int
00155 _s_scan_extensions(void *ptr, ftype_t type, int elsize, long *begin,
00156         int left, long *size, long cmode);
00157 
00158 /*
00159  *      Macros
00160  */
00161 
00162 /*
00163  *      GENREALTO8 converts a _gen_real to a _f_real8.
00164  */
00165 
00166 #ifdef  FAKE_REAL16
00167 #define GENREALTO8(x)   (*x)
00168 
00169 #elif   !defined(_UNICOS)
00170 #define GENREALTO8(x)   ((_f_real8)(*x))        /* cast to _f_real8 */
00171 
00172 #else
00173 #define SNGLR _SNGLR_
00174 
00175 #endif
00176 
00177 #ifdef  SNGLR
00178 #define GENREALTO8      SNGLR
00179 extern _f_real SNGLR(_f_real16 *);              
00180 #endif
00181 
00182 /*
00183  *      GENREALTO4 converts a _gen_real to a _f_real4.
00184  */
00185 
00186 #ifdef  _F_REAL4
00187 #define GENREALTO4(x)   ((_f_real4)(*x))        /* cast to _f_real4 */
00188 #endif
00189 
00190 /*
00191  *      ADVANCE_INPUT advances the file until it finds a non-whitespace
00192  *                      character.
00193  */
00194 
00195 #define ADVANCE_INPUT(css, cup, lptr, lcnt)     \
00196         for (;;) {                              \
00197                 while (lcnt == 0) { /* Find a non-empty line */         \
00198                         errn    = css->u.fmt.endrec(css, cup, 1);       \
00199                         if (errn != 0) {                                \
00200                                 if (errn > 0) RERROR(errn);             \
00201                                 if (errn < 0) REND(errn);               \
00202                         }                                               \
00203                         lptr    = cup->ulineptr;                        \
00204                         lcnt    = cup->ulinecnt;                        \
00205                 }                                                       \
00206                 if (! IS_WHITESPACE(*lptr))                             \
00207                         break;  /* Eureka! */                           \
00208                 lptr    = lptr + 1;                                     \
00209                 lcnt    = lcnt - 1;                                     \
00210         }
00211 
00212 /*
00213  *      _ld_read - read list formatted input.
00214  *
00215  *      return value:
00216  *              <0      end-of-file return
00217  *               0      normal return
00218  *              >0      error return
00219  *           abort      if error or end-of-file condition and user has not
00220  *                      specified IOSTAT=/ERR=/END=
00221  */
00222 
00223 int
00224 _ld_read(
00225         FIOSPTR         css,    /* Current Fortran I/O statement state */
00226         unit            *cup,   /* Unit pointer */
00227         void            *dptr,  /* Pointer to start of destination data area */
00228         type_packet     *tip,   /* Type information packet */
00229         int             _Unused)/* Unused by this routine */
00230 {
00231         register short  reptype;/* Local copy of cup->urepdata->reptype */
00232         register ftype_t type;  /* Fortran data type                    */
00233         register int    elsize; /* Size of each data item (bytes)       */
00234         register int    errn;   /* Error code                           */
00235         register int    lcnt;   /* Local copy of cup->ulinecnt          */
00236         register long   count;  /* Number of data items                 */
00237         register long   repcnt; /* Local copy of cup->urepdata->repcnt  */
00238         register long   stride; /* Stride between data items (bytes)    */
00239         register long   vinc;   /* Virtual stride                       */
00240         long            *lptr;  /* Local copy of cup->ulineptr          */
00241         char            *cptr;  /* Character pointer to datum           */
00242         struct repdata  *rptr;  /* Local copy of cup->urepdata          */
00243 #ifdef  _CRAYT3D
00244         register short  shared; /* Is variable shared?                  */
00245         register int    elwords;/* Number of words per data item        */
00246         register int    offset; /* Offset from address in item units    */
00247         register int    tcount; /* Number of items to move              */
00248         long            shrd[MAXSH];    /* Shared data temp array       */
00249 #endif
00250 
00251         /* Assertions */
00252 
00253         assert ( css != NULL );
00254         assert ( cup != NULL );
00255         assert ( dptr != NULL );
00256         assert ( tip != NULL );
00257 
00258         cptr    = (char *) dptr;
00259         errn    = 0;
00260 
00261         lcnt    = cup->ulinecnt;
00262         lptr    = cup->ulineptr;
00263 
00264         type    = tip->type90;
00265         count   = tip->count;
00266         elsize  = tip->elsize;
00267         vinc    = tip->stride;
00268 
00269 /*
00270  *      u.fmt.lcomma is 0 only if this is the first _ld_read call for the
00271  *      current list-directed READ statement.  Use this clue to be sure
00272  *      any old unexhausted repeat count is zeroed.
00273  */
00274 
00275         rptr    = cup->urepdata;
00276 
00277         if (css->u.fmt.lcomma == 0 && rptr != NULL)
00278                 rptr->repcnt    = 0;
00279 
00280         if (rptr != NULL && rptr->repcnt != 0) {
00281 
00282                 /*
00283                  * An unexhausted repeat count exists from a previous
00284                  * iteration or call to _ld_read.
00285                  */
00286 
00287                 reptype = rptr->reptype;
00288                 repcnt  = rptr->repcnt;
00289 
00290                 assert ( reptype == REPNONE || reptype == REPLINE ||
00291                          reptype == REPCHAR || reptype == REPCPLX ||
00292                          reptype == REPNULL );
00293                 assert ( repcnt > 0 );
00294         }
00295         else {
00296                 reptype = REPNONE;      /* Indicate no leftover repeat count */
00297                 repcnt  = 1;
00298         }
00299 
00300 #ifdef  _CRAYT3D
00301         if (_issddptr(dptr)) {
00302                 offset  = 0;
00303                 elwords = elsize / sizeof(long);
00304                 tcount  = count;
00305                 vinc    = 1;    /* We now have a unit stride */ 
00306                 shared  = 1;
00307                 css->f_shrdput  = 1;
00308         }
00309         else
00310                 shared  = 0;
00311 
00312    do   {
00313         if (shared) {   /* shared variable */
00314                 /* we read the data into local array shrd */
00315                 /* and later distribute it to shared memory */
00316                 count   = MIN(MAXSH / elwords, (tcount - offset));
00317                 cptr    = (char *) shrd;
00318         }
00319 #endif
00320 
00321         stride  = elsize * vinc;
00322 
00323         /*
00324          *      M A I N   L O O P
00325          */
00326 
00327         while (count > 0) {     /* While more to read */
00328                 register short  is_mult;/* Can complex scan advance? */
00329                 register short  is_null;/* Is value a null value? */
00330                 register long   nitems; /* Number of repeated data items */
00331                 long            width;  /* Field width of data */
00332 
00333                 if (css->u.fmt.slash)   /* If we've encountered a slash */
00334                         break;
00335 
00336                 is_null = 0;    /* Assume a non-null value */
00337                 is_mult = 1;    /* Complex scan may process multiple records */
00338 
00339                 /*
00340                  * If there is no outstanding repeat count, we must scan
00341                  * ahead, past a possible new repeat count, to the first
00342                  * character of the input data.
00343                  */
00344 
00345                 if (reptype == REPNONE) {
00346 
00347                         /*
00348                          * Read until we find a record containing a non-blank
00349                          * character.
00350                          */
00351 
00352 advance:
00353                         ADVANCE_INPUT(css, cup, lptr, lcnt);
00354 
00355                         /*
00356                          * If css->u.fmt.lcomma == 1 then the next 
00357                          * comma would not imply a null value.
00358                          */
00359 
00360                         if (*lptr == COMMA && css->u.fmt.lcomma == 1) {
00361                                 css->u.fmt.lcomma       = 0;
00362                                 lptr                    = lptr + 1;
00363                                 lcnt                    = lcnt - 1;
00364                                 goto advance;
00365                         }
00366 
00367                         css->u.fmt.lcomma       = 1;
00368                         repcnt                  = 1;
00369 
00370                         if (*lptr == SLASH) {
00371                                 css->u.fmt.slash        = 1;
00372                                 goto done;
00373                         }
00374 
00375                         /* Check for a possible repeat count in the input */
00376 
00377                         if (IS_DIGIT(*lptr)) {
00378 
00379                                 repcnt  = _get_repcount(lptr, lcnt, &width);
00380 
00381                                 lcnt    = lcnt - width;
00382                                 lptr    = lptr + width;
00383                         }
00384                 }
00385                 else if (reptype == REPLINE) {
00386 
00387                         /*
00388                          * Reposition at the location of the repeated
00389                          * data item.  Then redo the usual input scan.
00390                          */
00391 
00392                         lptr    = rptr->u.line.lptr;
00393                         lcnt    = rptr->u.line.lcnt;
00394 
00395                         /* Complex scan may not advance records */
00396 
00397                         is_mult = 0;
00398                 }
00399 
00400                 /*
00401                  * Scan the data at the current position in the current
00402                  * record.  We do this if there is no outstanding repeat
00403                  * count, or we are rescanning at the current record
00404                  * position to satisfy an outstanding repeat count of
00405                  * type REPLINE.
00406                  */
00407 
00408                 if (reptype == REPNONE || reptype == REPLINE) {
00409 
00410                         /* Check for a null value */
00411 
00412                         if (lcnt == 0 || IS_SEPARATOR(*lptr))
00413                                 is_null = 1;
00414 
00415                         if (repcnt <= count || reptype == REPLINE) {
00416                                 /*
00417                                  * Handle the case where this call to _ld_read
00418                                  * consumes all of the (optionally repeated)
00419                                  * data.
00420                                  */
00421 
00422                                 if (is_null)
00423                                         errn    = 0;    /* Do nothing */
00424                                 else switch (type) {
00425 
00426                                 default:
00427                                         errn    = _get_value(
00428                                                         lptr,
00429                                                         lcnt,
00430                                                         cptr,
00431                                                         type,
00432                                                         elsize,
00433                                                         &width);
00434 
00435                                         lcnt    = lcnt - width;
00436                                         lptr    = lptr + width;
00437                                         break;
00438 
00439                                 case DVTYPE_COMPLEX:
00440                                         cup->ulinecnt   = lcnt;
00441                                         cup->ulineptr   = lptr;
00442 
00443                                         errn    = _mr_scan_complex(
00444                                                         css,
00445                                                         cup,
00446                                                         cptr,
00447                                                         elsize,
00448                                                         is_mult);
00449 
00450                                         lcnt    = cup->ulinecnt;
00451                                         lptr    = cup->ulineptr;
00452                                         break;
00453 
00454                                 case DVTYPE_ASCII:
00455                                         cup->ulinecnt   = lcnt;
00456                                         cup->ulineptr   = lptr;
00457 
00458                                         errn    = _mr_scan_char(
00459                                                         css,
00460                                                         cup,
00461                                                         cptr,
00462                                                         elsize,
00463                                                         NULL,
00464                                                         NULL);
00465 
00466                                         lcnt    = cup->ulinecnt;
00467                                         lptr    = cup->ulineptr;
00468                                         break;
00469 
00470                                 } /* switch */
00471 
00472                                 if (errn != 0)  /* If EOF or error */
00473                                         goto done;
00474                         }
00475 
00476                         /*
00477                          * Else the repeat count exceeds the number of I/O
00478                          * list items, so create the repdata data structure.
00479                          * At the same time, read the data into the next I/O
00480                          * list item.
00481                          */
00482 
00483                         else {
00484                                 if (rptr == NULL) {
00485 
00486                                         rptr    = (struct repdata *)
00487                                                   malloc(sizeof(struct repdata));
00488 
00489                                         if (rptr == NULL) {
00490                                                 errn    = FENOMEMY;
00491                                                 goto done;
00492                                         }
00493 
00494                                         cup->urepdata   = rptr;
00495                                 }
00496 
00497                                 if (is_null) {
00498                                         errn    = 0;
00499                                         reptype = REPNULL;
00500                                 }
00501                                 else switch (type) {
00502 
00503                                 default:
00504                                         errn    = _get_value(
00505                                                         lptr,
00506                                                         lcnt,
00507                                                         cptr,
00508                                                         type,
00509                                                         elsize,
00510                                                         &width);
00511 
00512                                         reptype                 = REPLINE;
00513                                         rptr->u.line.lcnt       = lcnt;
00514                                         rptr->u.line.lptr       = lptr;
00515                                         lcnt                    = lcnt - width;
00516                                         lptr                    = lptr + width;
00517                                         break;
00518 
00519                                 case DVTYPE_COMPLEX:
00520                                         reptype         = REPCPLX;
00521                                         cup->ulinecnt   = lcnt;
00522                                         cup->ulineptr   = lptr;
00523 
00524                                         errn    = _mr_scan_complex(
00525                                                 css,
00526                                                 cup,
00527                                                 &rptr->u.cplx,
00528                                                 sizeof(rptr->u.cplx),
00529                                                 is_mult);
00530 
00531                                         lcnt    = cup->ulinecnt;
00532                                         lptr    = cup->ulineptr;
00533 
00534                                         _cmplx_convert(
00535                                                 cptr,
00536                                                 elsize,
00537                                                 rptr->u.cplx.r);
00538                                         break;
00539 
00540                                 case DVTYPE_ASCII:
00541                                         rptr->u.rchr.repchr     = NULL;
00542                                         cup->ulinecnt           = lcnt;
00543                                         cup->ulineptr           = lptr;
00544 
00545                                         errn    = _mr_scan_char(
00546                                                 css,
00547                                                 cup,
00548                                                 cptr,
00549                                                 elsize,
00550                                                 &rptr->u.rchr.repchr,
00551                                                 &rptr->u.rchr.repsize);
00552 
00553                                         if (rptr->u.rchr.repchr != NULL)
00554                                                 reptype                 = REPCHAR;
00555                                         else {
00556                                                 reptype                 = REPLINE;
00557                                                 rptr->u.line.lptr       = lptr;
00558                                                 rptr->u.line.lcnt       = lcnt;
00559                                         }
00560 
00561                                         lcnt    = cup->ulinecnt;
00562                                         lptr    = cup->ulineptr;
00563                                         break;
00564 
00565                                 } /* switch */
00566 
00567                                 if (errn != 0)  /* If EOR or error */
00568                                         goto done;
00569                         }
00570                 }
00571 
00572                 /*
00573                  * Else satisfy the first I/O list item from the leftover
00574                  * repeat count from a previous call to _ld_read.
00575                  */
00576 
00577                 else {
00578                         if (reptype == REPNULL) {
00579                                 errn    = 0;
00580                                 is_null = 1;
00581                         }
00582                         else switch (type) {
00583 
00584                         case DVTYPE_COMPLEX:
00585 
00586                                 if (reptype != REPCPLX)
00587                                         errn    = FELDNOCX;
00588                                 else
00589                                         _cmplx_convert(
00590                                                 cptr,
00591                                                 elsize,
00592                                                 rptr->u.cplx.r);
00593                                 break;
00594 
00595                         case DVTYPE_ASCII:
00596                                 if (reptype != REPCHAR)
00597                                         errn    = FELDUNKI;
00598                                 else {
00599                                         register int    xfersz;
00600 
00601                                         xfersz  = MIN(elsize,
00602                                                 rptr->u.rchr.repsize);
00603 
00604                                         if (xfersz > 0)
00605                                                 (void) memcpy(
00606                                                         cptr,
00607                                                         rptr->u.rchr.repchr,
00608                                                         xfersz);
00609 
00610                                         if (xfersz < elsize)
00611                                                 (void) memset(
00612                                                         cptr + xfersz,
00613                                                         BLANK,
00614                                                         elsize - xfersz);
00615                                 }
00616                                 break;
00617 
00618                         default:
00619                                 errn    = FELDUNKI;     /* Deep weeds */
00620                                 break;
00621 
00622                         } /* switch */
00623 
00624                         if (errn != 0)  /* If EOR or error */
00625                                 goto done;
00626                 }
00627 
00628                 /*
00629                  * Repeat count processing is now wrapped up by distributing
00630                  * copies of the first I/O list item to the rest of the
00631                  * items.
00632                  */
00633 
00634                 nitems  = MIN(repcnt, count);
00635 
00636                 if (nitems > 1 && is_null == 0)
00637                         _set_stride(cptr + stride, cptr, nitems - 1,
00638                                         elsize, stride);
00639 
00640                 cptr    = cptr + (nitems * stride);
00641                 count   = count - nitems;
00642                 repcnt  = repcnt - nitems;
00643 
00644                 if (repcnt == 0) {      /* If repeat count exhausted */
00645 
00646                         if (reptype == REPCHAR)
00647                                 free(rptr->u.rchr.repchr);
00648 
00649                         reptype = REPNONE;
00650                 }
00651         } /* while */
00652 
00653 done:
00654 #ifdef  _CRAYT3D
00655         if (shared && (long *)cptr != shrd) {
00656                 register int    items;
00657 
00658                 /* Move the data to shared memory */
00659 
00660                 items   = ((long *) cptr - shrd) / elwords;
00661 
00662                 _cpytosdd(dptr, shrd, items, elwords, tip->stride, offset);
00663 
00664                 offset  = offset + items;
00665         }
00666 
00667         if (css->u.fmt.slash)
00668                 break;
00669 
00670    } while (errn == 0 && shared && offset < tcount);
00671 #endif
00672 
00673         /*
00674          * Update fields in unit table.
00675          */
00676 
00677         cup->ulinecnt   = lcnt;
00678         cup->ulineptr   = lptr;
00679 
00680         if (rptr != NULL) {     /* If we have a repdata structure */
00681 
00682                 if (repcnt == 0) {      /* If repcnt exhausted */
00683 
00684                         if (reptype == REPCHAR)
00685                                 free(rptr->u.rchr.repchr);
00686 
00687                         reptype = REPNONE;
00688                 }
00689 
00690                 rptr->repcnt    = repcnt;
00691                 rptr->reptype   = (enum reptypes) reptype;
00692         }
00693 
00694         if (errn > 0)
00695                 RERROR(errn);
00696 
00697         return(errn);
00698 }
00699 
00700 /*
00701  *      _get_repcount - scan text for a positive integer repeat count followed
00702  *                      by an asterisk.
00703  *
00704  *      Return value:
00705  *              Repeat count (1 if no count found)
00706  *              Line position updated if repeat count found.
00707  */
00708  
00709 long
00710 _get_repcount(
00711         long    *ptr,   /* Pointer into current record buffer */
00712         int     limit,  /* Number of characters left in current record */
00713         long    *width) /* Number of characters consumed by repeat count */
00714 {
00715         register int    nchars; /* Number of characters processed */
00716         register long   chr;    /* Current character */
00717         register long   count;  /* Repeat count */
00718 
00719         chr     = *ptr++;
00720         count   = 0;
00721         nchars  = 0;
00722 
00723         while (limit > 1 && IS_DIGIT(chr)) {
00724                 count   = (count + count + (count << 3)) + (chr - ZERO);
00725                 chr     = *ptr++;
00726                 nchars  = nchars + 1;
00727                 limit   = limit - 1;
00728         }
00729 
00730         /*
00731          * If the repeat count is zero or not found, set the repeat count
00732          * to 1 but do not update the line position.
00733          */
00734 
00735         if (chr != STAR || count == 0) {        /* If no repeat count or zero */
00736                 count   = 1;            /* Update line position */
00737                 nchars  = 0;
00738         }
00739         else
00740                 nchars  = nchars + 1;   /* Count the asterisk */
00741 
00742         *width  = nchars;
00743 
00744         return(count);  /* Return repeat count */
00745 }
00746 
00747 /*
00748  *      _get_value      - Read a real, integer, or logical value.
00749  *
00750  *      Return value:
00751  *               0 on success
00752  *              >0 error code on error
00753  */
00754 
00755 int
00756 _get_value(
00757         long    *lptr,  /* Pointer to the unpacked text */
00758         int     lcnt,   /* Number of characters available to scan */
00759         void    *ptr,   /* Pointer to I/O list item */
00760         ftype_t type,   /* Fortran data type */
00761         int     elsize, /* Size in bytes of the I/O list item */
00762         long    *size)  /* Field width (output) */
00763 {
00764         register int    errn;
00765         register int    nc;
00766         long            dummy;
00767         long            cmode;
00768         long            zero = 0;
00769         long            width;
00770         long            *begin;
00771         long            *end;
00772         const ic_func   *ngcf;
00773 
00774         begin   = lptr;                 /* Mark start of field */
00775         ngcf    = _ilditab[type];       /* Conversion function */
00776         *size   = 0;
00777         nc      = 0;
00778         cmode   = 0;
00779 
00780         /* Find the trailing value separator */
00781 
00782         while ( nc < lcnt && !IS_DELIMITER(*lptr) ) {
00783                 lptr    = lptr + 1;
00784                 nc      = nc + 1;
00785         }
00786 
00787         end     = lptr;
00788         width   = nc;
00789 
00790         /* Set up cmode */
00791 
00792         switch (type) {
00793 
00794         case DVTYPE_REAL:
00795 
00796                 switch (elsize) {
00797 
00798 #ifdef  _F_REAL4
00799                 case 4:
00800                         cmode   = MODEHP;
00801                         break;
00802 #endif
00803                 case 8:
00804                         break;
00805 
00806                 case 16:
00807                         cmode   = MODEDP;
00808                         break;
00809 
00810                 default:
00811                         return(FEKNTSUP);       /* kind not supported */
00812                 }
00813                 break;
00814 
00815         case DVTYPE_INTEGER:
00816         case DVTYPE_LOGICAL:
00817 
00818                 switch (elsize) {
00819 
00820 #if     (defined(_F_INT2) || defined(_F_LOG2)) && (defined(__mips) || \
00821         defined(_LITTLE_ENDIAN))
00822                 case 1:         
00823                         cmode   = MODEBP;
00824                         break;
00825                 case 2:         
00826                         cmode   = MODEWP;
00827                         break;
00828 #endif
00829 #if     defined(_F_INT4) || defined(_F_LOG4)
00830                 case 4:         
00831                         cmode   = MODEHP;
00832                         break;
00833 #endif
00834                 case 8:
00835                         break;
00836 
00837                 default:
00838                         return(FEKNTSUP);       /* kind not supported */
00839                 }
00840                 break;
00841 
00842         default:
00843                 return(FEKNTSUP);       /* kind not supported */
00844         }
00845 
00846         /* Call the conversion function */
00847 
00848         errn    = ngcf( begin, &width, &end, &cmode, ptr, &dummy,
00849                         &zero, &zero);
00850 
00851         if (errn < 0)
00852                 errn    = _nicverr(errn); 
00853         else
00854                 errn    = 0;
00855 
00856 /*
00857  *      If the scan failed, the input data might be hollerith or hex or
00858  *      octal.  Allow _s_scan_extensions to rescan the input and recompute
00859  *      the field width.
00860  */
00861 
00862         if (errn == FENICVIC || errn == FERDIVLG) {
00863                 register int    errn2;
00864 
00865                 errn2   = _s_scan_extensions(
00866                         ptr,
00867                         type,
00868                         elsize,
00869                         begin,
00870                         lcnt,
00871                         size,
00872                         cmode);
00873 
00874                 if (errn2 >= 0)
00875                         errn    = errn2;
00876         }
00877         else
00878                 *size   = end - begin;
00879 
00880         return(errn);
00881 }
00882 
00883 /*
00884  *      _s_scan_extensions - read a Cray extension format into an I/O list item.
00885  *
00886  *      Input forms accepted ('Y' yes or '-' no):
00887  * 
00888  *      Data types
00889  *      I R L C         Format          Description
00890  *      - - - -         ------          -----------
00891  *
00892  *      Y Y Y Y         (o0)'nnn[']     Octal bit pattern
00893  *      Y Y Y Y         (zZ)'nnn[']     Hexadecimal bit pattern
00894  *      Y Y - Y         nnn(bB)         Octal integer (may be converted to real)
00895  *      Y Y Y Y         ("')xxx("')[hH] Blank-filled Hollerith character data
00896  *      Y Y Y Y         ("')xxx("')(lL) Zero-filled character data
00897  *      Y Y Y Y         ("')xxx("')(rR) Right-justified character data
00898  *
00899  *      Input forms accepted for data item sizes:
00900  * 
00901  *      Size (words)
00902  *      1 2+            Format
00903  *      - -             ------  
00904  *
00905  *      Y -             (o0)'nnn[']
00906  *      Y -             (zZ)'nnn[']
00907  *      Y Y             nnn(bB) (but the integer value must fit in one word)
00908  *      Y -             'xxxx'[hH]
00909  *      Y -             'xxxx'(lL)
00910  *      Y -             'xxxx'(rR)
00911  *
00912  *      Return value:
00913  *               0 on success
00914  *              >0 error code
00915  *              -1 use previously assigned error code
00916  */
00917 int
00918 _s_scan_extensions(
00919         void    *ptr,           /* Pointer to user I/O list item */
00920         ftype_t type,           /* Fortran data type */
00921         int     elsize,         /* Size in bytes of datum */
00922         long    *begin,         /* Pointer to start of input field */
00923         int     left,           /* Number of characters left in record */
00924         long    *size,          /* Field width (output) */
00925         long    cmode)          /* Mode from calling routine */
00926 {
00927         register short  nchars;
00928         register int    errn;
00929         register int    i;
00930         register int    lcnt;
00931         register long   delim;
00932         long            dummy;
00933         long            fw;
00934         long            zero = 0;
00935         register char   first;
00936         register char   ht;
00937         _f_int8         intvalue;
00938         char            cbuf[sizeof(_f_int8)];
00939         long            *endptr;
00940         long            *lptr;
00941         void            *vptr;
00942         ic_func         *ncf;   /* Numeric conversion function */
00943 
00944         *size   = 0;
00945         errn    = 0;
00946         lptr    = begin;
00947         lcnt    = left;
00948         first   = (char) *lptr;
00949 
00950         switch (first) {
00951 
00952         case 'b': 
00953         case 'B':                       /* Binary, F90 only */
00954                 if (first == 'b' || first == 'B')
00955                         return (FELDUNKI);
00956                 break;
00957 
00958         case 'o': 
00959         case 'O':                       /* Octal */
00960         case 'z': 
00961         case 'Z':                       /* Hexadecimal */
00962 
00963                 if (lcnt < 3 || lptr[1] != SQUOTE)
00964                         return(-1);
00965 
00966                 lptr    = lptr + 2;             /* advance past the [oOzZ]' */
00967                 lcnt    = lcnt - 2;
00968 
00969                 for (i = 0; i < lcnt; i++) {
00970                         if (IS_DELIMITER(lptr[i]))
00971                                 break;
00972                 }
00973 
00974                 if (lptr[i - 1] == SQUOTE)
00975                         i       = i - 1;        /* Exclude trailing ' */
00976 
00977                 if (i <= 0) 
00978                         return (-1);            /* No sequence of digits found */
00979 
00980                 if (first == 'b' || first == 'B')
00981                         return (FELDUNKI);
00982 
00983                 if (first == 'o' || first == 'O')
00984                         ncf     = _ou2s;
00985                 else    /* Assume hexadecimal */
00986                         ncf     = _zu2s;
00987 
00988                 endptr  = lptr + i;
00989                 fw      = i;
00990 
00991                 errn    = ncf(lptr, &fw, &endptr, &cmode, ptr, &dummy,
00992                                 &zero, &zero);
00993 
00994                 if (errn < 0) {
00995                         register int estat;
00996                         estat   = _nicverr(errn);
00997                         if (estat > 0)
00998                                 return(estat);
00999                 }
01000 
01001                 lptr    = lptr + fw;
01002                 lcnt    = lcnt - fw;
01003 
01004                 if (lcnt > 0 && *lptr == SQUOTE) { /* consume trailing ' */
01005                         lptr    = lptr + 1;
01006                         lcnt    = lcnt - 1;
01007                 }
01008 
01009                 break;
01010 
01011         case '\'':
01012         case '"':                       /* Hollerith */
01013                 delim   = (long) first;
01014                 nchars  = 0; 
01015 
01016                 for (;;) {
01017                         lptr    = lptr + 1;
01018                         lcnt    = lcnt - 1;
01019 
01020                         if (lcnt == 0)
01021                                 return(-1);
01022 
01023                         if (*lptr == delim) {
01024                                 lptr    = lptr + 1;
01025                                 lcnt    = lcnt - 1;
01026 
01027                                 if (lcnt == 0 || *lptr != delim)
01028                                         break;          /* loop exit */ 
01029                         }
01030 
01031                         if ((nchars >= sizeof(_f_int8)) || 
01032                                 (nchars >= elsize))
01033                                 return(FELDSTRL);       /* too long for 1 word*/
01034 
01035                         cbuf[nchars]    = (char) *lptr;
01036                         nchars          = nchars + 1;
01037                 }
01038 
01039                 if (lcnt == 0)
01040                         ht      = 'h';
01041                 else if (IS_SEPARATOR(*lptr))
01042                         ht      = 'h';
01043                 else {
01044                         switch (*lptr) {
01045                                 case 'h':
01046                                 case 'H':
01047                                         ht      = 'h';
01048                                         break;
01049 
01050                                 case 'l':
01051                                 case 'L':
01052                                         ht      = 'l';
01053                                         break;
01054 
01055                                 case 'r':
01056                                 case 'R':
01057                                         ht      = 'r';
01058                                         break;
01059 
01060                                 default:
01061                                         return(FELDUNKI);
01062                         }
01063 
01064                         lptr    = lptr + 1;
01065                 }
01066 
01067                 /* pad with nulls */
01068 
01069                 switch (elsize) {
01070 #ifdef  _F_REAL4
01071                         case 4:
01072                                 *(_f_int4 *)ptr = 0;
01073                                 break;
01074 #endif
01075                         case 8:
01076                                 *(_f_int8 *)ptr = 0;
01077                                 break;
01078 #if     (defined(_F_INT2) || defined(_F_LOG2)) && (defined(__mips) || \
01079         defined(_LITTLE_ENDIAN))
01080                         case 2:
01081                                 *(_f_int2 *)ptr = 0;
01082                                 break;
01083                         case 1:
01084                                 *((char *)ptr) = '\0';
01085                                 break;
01086 #endif
01087                 }       
01088 
01089                 if (nchars > 0) {
01090 
01091                         if (ht == 'r'){                 /* right justify */
01092                                 memcpy((char *)ptr+elsize-nchars, cbuf, nchars);
01093                         }
01094                         else
01095                                 (void) memcpy(ptr, cbuf, nchars);
01096                 }
01097 
01098                 if (ht == 'h' && nchars != sizeof(long)) {
01099                         register int    pad;
01100 
01101                         pad     = elsize - nchars;
01102 
01103                         (void) memset((char *)ptr + nchars, BLANK, pad);
01104                 }
01105 
01106                 break;
01107 
01108         default:                        /* Must be the nnnnnB form */
01109                 for (i = 0; i < lcnt; i++) {
01110                         if (IS_DELIMITER(lptr[i]))
01111                                 break;
01112                 }
01113 
01114                 i       = i - 1;                /* exclude 'b'/'B' */
01115 
01116                 if (i == 0) 
01117                         return (-1);            /* no digits prior to 'b'/'B' */
01118 
01119                 if (lptr[i] != 'B' && lptr[i] != 'b')
01120                         return (-1);            /* not terminated by 'b'/'B' */
01121 
01122                 vptr    = &intvalue;
01123                 endptr  = lptr + i;
01124                 fw      = i;
01125 
01126                 errn    = _ou2s(lptr, &fw, &endptr, &cmode, vptr, &dummy,
01127                                 &zero, &zero);
01128 
01129                 if (errn < 0) {
01130                         register int estat;
01131                         estat   = _nicverr(errn);
01132                         if (estat > 0)
01133                                 return(estat);
01134                 }
01135 
01136                 /*
01137                  * Unlike the z'nn and o'nn forms, nnB is converted to
01138                  * floating point for REAL input list items.
01139                  */
01140 
01141                 if (type == DVTYPE_REAL) {
01142                         switch (elsize) {
01143 #ifdef  _F_REAL4
01144                         case 4:
01145                                 *(_f_real4 *)ptr        = (_f_real4)intvalue;
01146                                 break;          
01147 #endif
01148                         case 8:
01149                                 *(_f_real8 *)ptr        = (_f_real8)intvalue;
01150                                 break;
01151 
01152 #if     defined(_F_REAL16) && !defined(FAKE_REAL16)
01153                         case 16:
01154                                 *(_f_real16 *)ptr       = (_f_real16)intvalue;
01155                                 break;
01156 #endif
01157                         default:
01158                                 return (FEKNTSUP);
01159                         }
01160                 }
01161                 else {
01162                         switch (elsize) {
01163 #if     (defined(_F_INT2) || defined(_F_LOG2)) && (defined(__mips) || \
01164         defined(_LITTLE_ENDIAN))
01165                         case 2:
01166                                 *(_f_int2 *)ptr = (_f_int2)intvalue;
01167                                 break;
01168                         case 1: 
01169                                 *(_f_int1 *)ptr = (_f_int1)intvalue;
01170                                 break;
01171 #endif
01172 #ifdef  _F_INT4
01173                         case 4:
01174                                 *(_f_int4 *)ptr = (_f_int4)intvalue;
01175                                 break;
01176 #endif
01177 
01178 #ifdef  _F_INT8
01179                         case 8:
01180                                 *(_f_int8 *)ptr = intvalue;
01181                                 break;
01182 #endif
01183                         default:
01184                                 return (FEKNTSUP);
01185                         }
01186                 }
01187                 
01188                 lptr    = lptr + fw + 1;        /* Advance past nnnnB */
01189 
01190         }
01191 
01192         *size   = lptr - begin;
01193 
01194         return(0);
01195 }
01196 
01197 /*
01198  *      _mr_scan_complex        Read a complex value starting from the current
01199  *                      position in the current record.  If is_mult is set,
01200  *                      then scanning may continue into subsequent records.
01201  *
01202  *      Return value:
01203  *               0 on success.
01204  *              >0 on error.
01205  *              <0 on end-of-file.
01206  *           abort if error or end-of-file condition and user has not
01207  *                 specified IOSTAT=/ERR=/END=
01208  */
01209 
01210 int
01211 _mr_scan_complex(
01212         FIOSPTR css,            /* Fortran statement state */
01213         unit    *cup,           /* unit pointer */
01214         void    *cpxptr,        /* pointer to the complex input list item */
01215         int     elsize,         /* size in bytes of each input list item */
01216         short   is_mult)        /* 1 if we may advance to the next record */
01217 {
01218         register int    errn;
01219         register int    lcnt;
01220         long            fw;
01221         long            *lptr;
01222 
01223         lcnt    = cup->ulinecnt;
01224         lptr    = cup->ulineptr;
01225 
01226         if (*lptr != LPAREN) {  /* If no opening parenthesis */
01227                 errn    = FELDNOCX;
01228                 goto done;
01229         }
01230 
01231         lptr    = lptr + 1;
01232         lcnt    = lcnt - 1;
01233 
01234         /* Advance to the start of the numeric field for the real part */
01235 
01236         while (lcnt > 0 && IS_WHITESPACE(*lptr)) {
01237                 lptr    = lptr + 1;
01238                 lcnt    = lcnt - 1;
01239         }
01240 
01241         if (lcnt == 0) {
01242                 errn    = FELDNOCX;
01243                 goto done;
01244         }
01245 
01246         elsize  = elsize >> 1;          /* Size of each complex part */
01247 
01248         errn    = _get_value(lptr, lcnt, cpxptr, DVTYPE_REAL, elsize, &fw);
01249 
01250         if (errn != 0)
01251                 goto done;
01252 
01253         lptr    = lptr + fw;
01254         lcnt    = lcnt - fw;
01255 
01256         /* Now advance to the comma */
01257 
01258         while (lcnt > 0 && IS_WHITESPACE(*lptr)) {
01259                 lptr    = lptr + 1;
01260                 lcnt    = lcnt - 1;
01261         }
01262 
01263         if (lcnt == 0) {        /* If at end of line */
01264 
01265                 if (is_mult == 0) {
01266                         errn    = FELDNOCX;
01267                         goto done;
01268                 }
01269 
01270                 ADVANCE_INPUT(css, cup, lptr, lcnt);
01271         }
01272 
01273         if (*lptr != COMMA) {   /* If no comma between real and imaginary parts */
01274                 errn    = FELDNOCX;
01275                 goto done;
01276         }
01277 
01278         lptr    = lptr + 1;
01279         lcnt    = lcnt - 1;
01280 
01281         /* Advance to the start of the numeric field for the imaginary part */
01282 
01283         while (lcnt > 0 && IS_WHITESPACE(*lptr)) {
01284                 lptr    = lptr + 1;
01285                 lcnt    = lcnt - 1;
01286         }
01287 
01288         if (lcnt == 0) {        /* If at end of line */
01289                 ADVANCE_INPUT(css, cup, lptr, lcnt);
01290         }
01291 
01292 /*
01293  *      Scan the imaginary part.
01294  */
01295         cpxptr  = (char *) cpxptr + elsize;
01296 
01297         errn    = _get_value(lptr, lcnt, cpxptr, DVTYPE_REAL, elsize, &fw);
01298 
01299         if (errn != 0)
01300                 goto done;
01301 
01302         lptr    = lptr + fw;
01303         lcnt    = lcnt - fw;
01304 
01305         /* Advance past the trailing parenthesis */
01306 
01307         while (lcnt > 0 && *lptr != RPAREN) {
01308                 lptr    = lptr + 1;
01309                 lcnt    = lcnt - 1;
01310         }
01311 
01312         if (lcnt == 0) {        /* Didn't find closing parenthesis! */
01313                 errn    = FELDNOCX;
01314                 goto done;
01315         }
01316 
01317         cup->ulineptr   = lptr + 1;
01318         cup->ulinecnt   = lcnt - 1;
01319 
01320 done:
01321         if (errn > 0)
01322                 RERROR(errn);
01323 
01324         return(0);
01325 }
01326 
01327 /*
01328  *      _mr_scan_char - read a character value.
01329  *
01330  *      This routine reads delimited or undelimited character strings for
01331  *      list-directed input.  Scanning starts from the current position in the
01332  *      current record.  If the string is delimitted by quotes or characters,
01333  *      additional records are read when necessary to reach the trailing 
01334  *      delimiter.
01335  *
01336  *      The character string is transferred to the I/O list item pointed
01337  *      to by ptr.  The I/O list item is properly padded with blanks if
01338  *      the string is shorter than the I/O list item.  If the I/O list item
01339  *      is shorter than the input string, the whole string is scanned 
01340  *      anyway with extra characters being discarded.
01341  *
01342  *      Return value:
01343  *               0 on success.
01344  *              >0 on error.
01345  *              <0 on end-of-file.
01346  *           abort if error or end-of-file condition and user has not
01347  *                 specified IOSTAT=/ERR=/END=
01348  */
01349 int
01350 _mr_scan_char(
01351         FIOSPTR css,            /* Fortran statement state */
01352         unit    *cup,           /* unit pointer */
01353         char    *ptr,           /* pointer to the character input list item */
01354         int     elsize,         /* size in bytes of each input list item */
01355         char    **chptr,        /* (input) chptr is non-null if a copy of 
01356                                  * multi-record strings should be saved.
01357                                  * (output) *chptr is assigned NULL if the
01358                                  * string didn't span records or string is
01359                                  * of zero length.  Assigned a pointer to an 
01360                                  * allocated buffer containing a copy of the 
01361                                  * string. */
01362         long    *slen)          /* (output) size of string saved at *chptr */
01363 {
01364         register short  span;   /* Input spanned records?               */
01365         register int    errn;   /* Error code                           */
01366         register int    lcnt;   /* Local copy of cup->ulinecnt          */
01367         register long   chlen;  /* Length of the character string       */
01368         register long   delim;  /* Character string delimiter           */
01369         register long   lsave;  /* Length of character save buffer      */
01370         long            *lptr;  /* Local copy of cup->ulineptr          */
01371         char            *csave; /* Character save buffer                */
01372 
01373         span    = 0;
01374         chlen   = 0;
01375         lsave   = 0;
01376         csave   = NULL;
01377         lptr    = cup->ulineptr;
01378         lcnt    = cup->ulinecnt;
01379         delim   = *lptr;        /* Possible delimiter */
01380 
01381         if (IS_STRING_DELIMITER(delim)) {       /* If quoted character */
01382 
01383                 for (;;) {
01384 
01385                         lptr    = lptr + 1;
01386                         lcnt    = lcnt - 1;
01387 
01388                         /* Advance to a nonempty record */
01389 
01390                         while (lcnt == 0) {
01391                                 span    = 1; 
01392 
01393                                 errn    = css->u.fmt.endrec(css, cup, 1);
01394 
01395                                 if (errn != 0) 
01396                                         goto err_end_return;
01397 
01398                                 lptr    = cup->ulineptr;
01399                                 lcnt    = cup->ulinecnt;
01400                         }
01401 
01402                         if (*lptr == delim) {
01403 
01404                                 if (lcnt > 1 && *(lptr + 1) == delim) {
01405                                         lptr    = lptr + 1;
01406                                         lcnt    = lcnt - 1;
01407                                 }
01408                                 else
01409                                         break;          /* loop exit */ 
01410                         }
01411 
01412                         if (chlen < elsize)
01413                                 ptr[chlen]      = (char) *lptr;
01414 
01415                         if (chptr != NULL) {    /* If saving input */
01416 
01417                                 if (csave == NULL) {
01418                                         lsave   = RECMAX;
01419                                         csave   = (char *) malloc(lsave);
01420 
01421                                         if (csave == NULL) {
01422                                                 errn    = FENOMEMY;
01423                                                 goto err_end_return;
01424                                         }
01425                                 }
01426                                 else {
01427                                         if (chlen > lsave) {
01428                                                 lsave   = lsave + RECMAX;
01429                                                 csave   = (char *) realloc(csave, lsave);
01430 
01431                                                 if (csave == NULL) {
01432                                                         errn    = FENOMEMY;
01433                                                         goto err_end_return;
01434                                                 }
01435                                         }
01436                                 }
01437 
01438                                 csave[chlen]    = (char) *lptr;
01439                         }
01440 
01441                         chlen   = chlen + 1;
01442                 } /* for */
01443 
01444                 lptr    = lptr + 1;     /* advance past trailing delimiter */
01445                 lcnt    = lcnt - 1;
01446 
01447                 if (span == 0) {        /* input didn't span records */
01448                         if (csave != NULL)
01449                                 free(csave);    /* don't need it */
01450                 }
01451                 else {                  /* input spanned records */
01452                         if (chptr != NULL) {    /* If saving input */
01453                                 *chptr  = csave;        /* Character save buffer */
01454                                 *slen   = chlen;        /* Set length */
01455                         }
01456                 }
01457         }
01458         else {  /* Unquoted character string */
01459                 while ( lcnt > 0 && !IS_SEPARATOR(*lptr) ) {
01460 
01461                         if (chlen < elsize)
01462                                 ptr[chlen]      = (char) *lptr;
01463 
01464                         chlen   = chlen + 1;
01465                         lptr    = lptr + 1;
01466                         lcnt    = lcnt - 1;
01467                 }
01468         }
01469 
01470         /* If input shorter than variable, pad with blanks */
01471 
01472         if (chlen < elsize)
01473                 (void) memset(ptr + chlen, BLANK, elsize - chlen);
01474 
01475         cup->ulineptr   = lptr;
01476         cup->ulinecnt   = lcnt;
01477 
01478         return(0);      /* normal return */
01479 
01480 err_end_return:
01481         if (csave != NULL)
01482                 free(csave);
01483 
01484         if (errn < 0) {
01485                 REND(errn);
01486         }
01487         else if (errn > 0) {
01488                 RERROR(errn);
01489         }
01490         else
01491                 _ferr(css, FEINTUNK);
01492 
01493         return(0);              /* MIPS compiler needs a return statement */
01494 }
01495 
01496 _PRAGMA_INLINE(_cmplx_convert)
01497 void
01498 _cmplx_convert(
01499         void            *dest,
01500         int             size,
01501         _gen_real       src[2])
01502 {
01503         /* Assertions */
01504 
01505         assert ( size <= (sizeof(_gen_real) << 1) );
01506 
01507         switch (size) { /* case for each supported complex kind */ 
01508 
01509 #ifdef  _F_COMP4
01510         case ( 2 * 4 ):                                 /* KIND=4 */
01511                 ((_f_real4 *)dest)[0]   = GENREALTO4(&src[0]);
01512                 ((_f_real4 *)dest)[1]   = GENREALTO4(&src[1]);
01513                 break;
01514 #endif
01515 
01516         case ( 2 * 8 ):                                 /* KIND=8 */
01517                 ((_f_real8 *)dest)[0]   = GENREALTO8(&src[0]);
01518                 ((_f_real8 *)dest)[1]   = GENREALTO8(&src[1]);
01519                 break;
01520 
01521 #ifdef  _F_COMP16
01522         case ( 2 * 16 ):                                /* KIND=16 */
01523                 ((_f_real16 *)dest)[0]  = src[0];
01524                 ((_f_real16 *)dest)[1]  = src[1];
01525                 break;
01526 #endif
01527 
01528         default:
01529                 assert ( 0 );   /* shouldn't happen */
01530         } /* switch */
01531 
01532         return;
01533 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines