Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
rnl90.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/rnl90.c    92.9    10/12/99 13:16:22"
00039 
00040 #include <stdio.h>
00041 #include <errno.h>
00042 #include <liberrno.h>
00043 #include <fortran.h>
00044 #include <stdlib.h>
00045 #include <cray/fmtconv.h>
00046 #include <cray/nassert.h>
00047 #if !defined(_ABSOFT)
00048 #include <sys/unistd.h>
00049 #endif
00050 #include "fio.h"
00051 #include "namelist.h"
00052 #include "rnl90def.h"
00053 
00054 /* EXTERNAL entry points */
00055 extern int _s_scan_extensions(void *ptr, ftype_t type,
00056         unsigned long elsize, long *field_begin,
00057         unsigned long rec_chars, int *fwptr, long cmode);
00058 extern int _nicverr(const int _Nicverror);
00059 
00060 /* use SUBGTC when the character retrieval cannot hit an end of file until
00061  * the retrieval is complete.  This occurs when retrieving the characters of
00062  * a name.  This macro is used in functions outside the main namelist FRN
00063  * routine.
00064  */
00065 
00066 #define SUBGTC(x) {                                     \
00067         while (cup->ulinecnt == 0) {                    \
00068                 if (errn = _nlrd_fillrec(css, cup)) {   \
00069                         return(errn);                   \
00070                 }                                       \
00071         }                                               \
00072         x       = (char) *cup->ulineptr++;              \
00073         cup->ulinecnt--;                                \
00074 }
00075 
00076 #define SUBGTCNOEOR(x) {                                \
00077         if (!cup->ulinecnt) {                           \
00078                 x       = ' ';                          \
00079         } else {                                        \
00080                 x       = (char) *cup->ulineptr++;      \
00081                 cup->ulinecnt--;                        \
00082         }                                               \
00083 }
00084 
00085 /* Fortran 95 provides an exclamation point as an input record
00086  * comment character.  Prepare for its addition in 3.0+.  If
00087  * comment begins an input record, ignore the rest of the
00088  * input record and get the next input record.
00089  */
00090 
00091 #define CMTE_SUBGTC(x) {                                \
00092         while (cup->ulinecnt == 0) {                    \
00093                 if (errn = _nlrd_fillrec(css, cup)) {   \
00094                         return(errn);                   \
00095                 }                                       \
00096         }                                               \
00097         x       = (char) *cup->ulineptr++;              \
00098         if (x == '!') {                                 \
00099                 x       = ' ';                          \
00100                 cup->ulinecnt   = 1;                    \
00101         }                                               \
00102         cup->ulinecnt--;                                \
00103 }
00104 
00105 #define CMTE_SUBGTCNOEOR(x) {                           \
00106         if (!cup->ulinecnt) {                           \
00107                 x       = ' ';                          \
00108         } else {                                        \
00109                 x       = (char) *cup->ulineptr++;      \
00110                 cup->ulinecnt--;                        \
00111         }                                               \
00112         if (x == '!') {                                 \
00113                 x       = ' ';                          \
00114                 cup->ulinecnt   = 0;                    \
00115         }                                               \
00116 }
00117                 
00118 
00119 
00120 /* use MAINGT when the character retrieval can hit an end of file before 
00121  * retrieval is complete.  This occurs when retrieving '=', delimiters,
00122  * , etc.  This macro is used in functions within the main namelist FRN
00123  * routine.  CMTE_MAINGT is the same except comments are allowed for F95.
00124  */
00125 
00126 #define MAINGT(x) {                                             \
00127         while (cup->ulinecnt == 0) {                            \
00128                 if (errn = _nlrd_fillrec(css, cup)) {           \
00129                         if (errn < 0) {                         \
00130                                 ENDD(endf, css, FERDPEOF);      \
00131                         }                                       \
00132                         else {                                  \
00133                                 ERROR0(errf, css, errn);        \
00134                         }                                       \
00135                 }                                               \
00136         }                                                       \
00137         x       = (char) *cup->ulineptr++;                      \
00138         cup->ulinecnt--;                                        \
00139 }
00140 
00141 #define CMTE_MAINGT(x) {                                        \
00142         while (cup->ulinecnt == 0) {                            \
00143                 if (errn = _nlrd_fillrec(css, cup)) {           \
00144                         if (errn < 0) {                         \
00145                                 ENDD(endf, css, FERDPEOF);      \
00146                         }                                       \
00147                         else {                                  \
00148                                 ERROR0(errf, css, errn);        \
00149                         }                                       \
00150                 }                                               \
00151         }                                                       \
00152         x       = (char) *cup->ulineptr++;                      \
00153         /* CHECK for comment */                                 \
00154         if (x == '!') {                                         \
00155                 x       = ' ';                                  \
00156                 cup->ulinecnt   = 1;                            \
00157         }                                                       \
00158         cup->ulinecnt--;                                        \
00159 }
00160 
00161 #define GETSECTION(x) {  \
00162                 field_begin     = cup->ulineptr;                \
00163                 field_end       = cup->ulineptr;                \
00164                 for (j = 0; j < cup->ulinecnt; j++) {           \
00165                         x       = (char) *field_end;            \
00166                         if (x == ')' || x == ',' || x == ':')   \
00167                                 break;                          \
00168                         field_end++;                            \
00169                 }                                               \
00170                 field_width     = j;                            \
00171 }
00172 
00173 /*
00174  *      This table is used to drive the f90 input conversion based on the
00175  *      type of the data.
00176  */
00177 ic_func *ncf_tab90[] = {
00178         NULL,           /* DVTYPE_UNUSED */
00179         NULL,           /* DVTYPE_TYPELESS */
00180         _iu2s,          /* DVTYPE_INTEGER */
00181         _defgu2sd,      /* DVTYPE_REAL */
00182         _defgu2sd,      /* DVTYPE_COMPLEX */
00183         NULL,           /* DVTYPE_LOGICAL */
00184         NULL,           /* DVTYPE_ASCII */
00185 };
00186 
00187 static int _nlrd_fillrec(FIOSPTR css, unit *cup);
00188 
00189 static int _getname(FIOSPTR css, unit *cup, char *buf, char *lastc);
00190 
00191 static void _cnvrt_toupper(char *bufr);
00192 
00193 static nmlist_goli_t *_findname(char *key, nmlist_goli_t *nlvar,
00194                 unsigned countitm);
00195 
00196 static int _getnlval(FIOSPTR css, nmlist_goli_t *nlvar, char *lastc, 
00197         unit *cup);
00198 
00199 static int _indx_nl(FIOSPTR css, unit *cup, struct DvDimen *dvdn,
00200    int *ndim, long strbegend[3], int *encnt, int *icnt, int arryflag);
00201 
00202 static int _nlrdent(FIOSPTR css,unit *cup,nmlist_goli_t *nalist,
00203         unsigned count, char *lastc, int byt);
00204 
00205 static int _nlread(FIOSPTR css, ftype_t type, unit *cup, void *ptr,
00206    long elsize, int cnt, int inc, char *lastc);
00207 
00208 static int _nexdata(FIOSPTR css, ftype_t type, void *ptr, int cnt, int inc,
00209    char lastc, unit *cup, long *lval, int *lcount, long elsize, int *nullvlu);
00210 
00211 static int _g_charstr(FIOSPTR css, unit *cup, void *p, int cnt, char c,
00212    int lcount, long elsize, int *nullvlu);
00213 
00214 static int _g_complx(FIOSPTR css, unit *cup, ftype_t type, long *lval,
00215    long elsize);
00216 
00217 static int _g_number(ftype_t type, unit *cup,long *lval, long elsize);
00218 
00219 static int _gocthex(FIOSPTR css, unit *cup, ftype_t type, long *lval, int base,
00220    long elsize, int *nullvlu);
00221 
00222 static int _get_holl(FIOSPTR css, unit *cup, char holltype, int count,
00223         ftype_t type, long *lval, long elsize);
00224 
00225 static int  _get_quoholl(FIOSPTR css, unit *cup, char cdelim, ftype_t type,
00226    long *lval, long elsize);
00227 
00228 static int _nl_stride_dv(FIOSPTR css, unit *cup, DopeVectorType *dv,
00229         struct DvDimen *sectn, char *lastc, long strbegend[3]);
00230 
00231 static int _nl_strd_derv( FIOSPTR css, unit *cup, DopeVectorType *dv,
00232    struct DvDimen *sectn, char *lastch, nmlist_goli_t *vdr,
00233    unsigned int cnt, long bte);
00234 
00235 /*
00236  *      _FRN    - called by compiled Fortran programs to process a namelist 
00237  *                read statement.
00238  *      Synopsis
00239  *              int _FRN(       ControlListType *cilist,
00240  *                              nmlist_group *namlist,
00241  *                              void *stck);
00242  *              Where
00243  *                      cilist  - pointer to the control information list
00244  *                                information.  This describes the specifiers
00245  *                                for the current I/O statement.
00246  *                      namlist  - pointer to the namelist table.
00247  *                      stck    - pointer to stack space which is passed
00248  *                                to each call to _FRU for a particular
00249  *                                statement.  This is used by the library.
00250  *      Return value
00251  *              IO_OKAY, IO_END, or IO_ERR
00252  */
00253 
00254 int
00255 _FRN(ControlListType *cilist, nmlist_group *namlist, void *stck)
00256 {
00257         char            buf[MAXNAML + 5], c;
00258         int             errf;           /* Error processing flag        */
00259         int             endf;           /* EOF processing flag          */
00260         int             errn;           /* Error number                 */
00261         register unum_t unum;           /* Actual unit number           */
00262         unit            *cup;           /* Pointer to unit table entry  */
00263         unsigned long   rlen;           /* group name length            */
00264         unsigned long   rcount;         /* count of namelist items      */
00265         char            *rptr;          /* pointer to group name        */
00266         char            *varptr;        /* ptr to group_obj_list item   */
00267         unsigned long   varlen;         /* len of group_obj_list name   */
00268         nmlist_goli_t   *nlvar;         /* ptr to next variable entry   */
00269         nmlist_goli_t   *fdvar;         /* ptr to next variable entry   */
00270         ftype_t         type;
00271         char            endnmlchar;     /* namelist group name char     */
00272         FIOSPTR         css;
00273 
00274         /* Assertions */
00275         /* Validate that the size of *stck is large enough */
00276         assert ( cilist->stksize >= sizeof(struct fiostate)/sizeof(long) );
00277 
00278         /* The compiler flags namelist with fmt flag */
00279         assert( (cilist->fmt == CI_NAMELIST));
00280 
00281         /* The compiler disallows namelist with internal files */
00282         assert( !(cilist->internal && cilist->fmt == CI_NAMELIST));
00283 
00284         /* The compiler disallows namelist with direct files */
00285         assert( !(cilist->dflag && cilist->fmt == CI_NAMELIST));
00286 
00287         css     = stck;
00288         errn    = 0;
00289         type    = DVTYPE_UNUSED;
00290         varptr  = NULL;
00291 
00292 /* **************************************************************************
00293  *      Statement Initialization Section
00294  ************************************************************************* */
00295 
00296         /* Establish error processing options */
00297         errf    = (cilist->errflag || cilist->iostatflg);
00298         endf    = (cilist->endflag || cilist->iostatflg);
00299 
00300         if (cilist->uflag == CI_UNITASTERK)
00301                 unum    = STDIN_U;
00302         else
00303                 unum    = *cilist->unit.wa;
00304 
00305         STMT_BEGIN(unum, 0, T_RNL, NULL, css, cup);
00306 
00307         if (cup == NULL) {      /* If not connected */
00308                 cup     = _imp_open(css, SEQ, FMT, unum, errf, &errn);
00309                 /*
00310                  * If the open failed, cup is NULL and errn contains
00311                  * the error number.
00312                  */
00313                 if (cup == NULL)
00314                         goto finalization;
00315         }
00316         /* All paths which lead here have set cup to a non-null value */
00317         assert (cup != NULL);
00318 
00319         /* Copy the user's error processing options into the unit table */
00320         cup->uflag      = (cilist->errflag              ?  _UERRF : 0) |
00321                           (cilist->endflag              ?  _UENDF : 0) |
00322                           (cilist->iostat_spec != NULL  ? _UIOSTF : 0);
00323         css->u.fmt.nonadv       = 0;
00324 
00325         /* If trying to read a file without read permission */
00326         if ((cup->uaction & OS_READ) == 0) {
00327                 errn    = FENOREAD;
00328                 ERROR0(errf, css, errn);
00329         }
00330         /* If attempting formatted I/O on an unformatted file */
00331         if (!cup->ufmt) {
00332                 errn    = FEFMTTIV;
00333                 ERROR0(errf, css, errn);
00334         }
00335         /* If sequential and writing, disallow read after write */
00336         if (cup->useq && cup->uwrt != 0) {
00337                 errn    = FERDAFWR;
00338                 ERROR0(errf, css, errn);
00339         }
00340 
00341         /* Preset fields in unit table */
00342 
00343         cup->uwrt       = 0;
00344 
00345         /* Initialize fields in the Fortran statement state structure */
00346 
00347         css->u.fmt.icp          = NULL;
00348         css->u.fmt.blank0       = cup->ublnk;
00349         css->u.fmt.lcomma       = 0;
00350         css->u.fmt.slash        = 0;
00351 
00352         if (cup->useq == 0) {   /* If seq. attempted on direct file */
00353                 errn    = FESEQTIV;     /* Sequential not allowed */
00354                 ERROR0(errf, css, errn);
00355         }
00356         /* external sequential formatted I/O */
00357         if (cup->uend && !cup->umultfil) {      /* If after endfile */
00358                 errn    = FERDENDR;     /* Read after endfile */
00359                 ERROR0(endf, css, errn);
00360         }
00361 
00362         css->u.fmt.endrec       = _sr_endrec;
00363 
00364         if (cup->pnonadv == 0)          /* if previous ADVANCE='YES' */
00365                 errn    = (*css->u.fmt.endrec)(css, cup, 1); /* Read a record */
00366         else                            /* else previous ADVANCE='NO' */
00367                 css->u.fmt.leftablim    = cup->ulineptr; /* set left tablimit */
00368 
00369         if (errn != 0)
00370                 if (errn < 0 ) {
00371                         ENDD(endf, css, FERDPEOF);
00372                 }
00373                 else {
00374                         ERROR0(errf, css, errn);
00375                 }
00376         cup->pnonadv    = css->u.fmt.nonadv;    /* remember prev ADVANCE= */
00377 
00378 /* **************************************************************************
00379  *      Data Transfer Section
00380  ************************************************************************* */
00381 
00382 #if defined(__mips) || !defined(_WORD32)
00383         if (!(cup->uft90)) {
00384                 errn    = _rnl90to77(css, cup, namlist, stck, errf, endf);
00385                 goto finalization;
00386 
00387         }
00388 #endif
00389 skiprec:
00390         while (cup->ulinecnt == 0) {
00391                 errn    = _nlrd_fillrec(css, cup);
00392                 if (errn != 0)
00393                         goto err_eof;
00394         }
00395 rrd:
00396         do {
00397                 CMTE_MAINGT(c)
00398         } while (ISBLANK(c));
00399         if (c != '&' && c != '$') {
00400                 /* irix f77 and f90, and 'assign -Y on' skip an input
00401                  * record when the first part of the record is not an
00402                  * ampersand or dollar sign delimiting a namelist
00403                  * group name.
00404                  */
00405                 if ((cup->ufnl_skip != 0) ||
00406                     (cup->ufcompat == AS_IRIX_F77) ||
00407                     (cup->ufcompat == AS_IRIX_F90)) {
00408                         cup->ulinecnt   = 0;
00409                         goto skiprec;
00410                 }
00411                 errn    = FENLONEC;
00412                 ERROR0(errf, css, errn);
00413         }
00414         /* save beginning character to check against ending char */
00415         endnmlchar      = c;
00416 
00417         /* get first character of namelist group name from input record */
00418         MAINGT(c);
00419         /* and get namelist group name from input record */
00420         errn    = _getname(css, cup, buf, &c);
00421         if (errn != 0)
00422                 goto err_eof;
00423         /* convert group name to uppercase */
00424         _cnvrt_toupper(buf);
00425 
00426         assert ( (cup != NULL));
00427         rcount  = namlist->icount;      /* number of name table entries */
00428         rptr    = _fcdtocp(namlist->group_name); /* ptr to groupname    */
00429         rlen    = _fcdlen(namlist->group_name); /* len of groupname     */
00430         nlvar   = namlist->goli;                /* group object ptr     */
00431 
00432         if (strncmp(rptr,buf,rlen)) {
00433                 if (cup->ufnl_skip == 0) {
00434                         errn    = FENLIVGP;
00435                         ERROR1(errf, css, errn, buf);
00436                 }
00437 
00438                 /* Skip unmatched namelist group. The slash terminates
00439                  * the f90 namelist input.
00440                  */
00441                 while (c != '/') {
00442 
00443                         /* check to see if old namelist ending (&END)
00444                          * is present rather than the slash in f90.
00445                          */
00446                         if (c == '&' || c == '$') {
00447 
00448                                 /* check to see that beginning namelist
00449                                  * group name delimiter matches the
00450                                  * ending delimiter before END.
00451                                  */
00452                                 if (c == endnmlchar) {
00453 
00454                                         /* get END, if present. */
00455                                         do {
00456                                                 MAINGT(c);
00457                                         } while (!ISBLANK(c));
00458                                         goto rrd;
00459                                 }
00460                         }
00461 
00462                         /* check for delimited character string */
00463                         if ((c == '\'') || (c == '"')) {
00464                                 char    qcr;
00465                                 qcr     = c;
00466 rqte:
00467                                 do {
00468                                         MAINGT(c);
00469                                 } while (c != qcr);
00470                                 MAINGT(c);
00471                                 /* embedded double quote? */
00472                                 if (c == qcr)
00473                                         goto rqte;
00474                         } else {
00475                                 CMTE_MAINGT(c);
00476                         }
00477                 }
00478 
00479                 goto rrd;
00480         }
00481         /*
00482          *      This is the correct namelist group name.  Process the
00483          *      input record. Read until the input record or records
00484          *      until the terminating character is found.  This is a
00485          *      slash or ampersand or MRNLDELIM.
00486          */
00487         while (c != '/') {
00488                 int     sepcnt;
00489                 if (c == '&' || c == '$') {
00490                         if (c != endnmlchar) {
00491                                 /* begin character did not match end char */
00492                                 errn    = FENLONEC;
00493                                 ERROR0(errf, css, errn);
00494                         }
00495                         else
00496                                 goto finalization;
00497                 }
00498                 /* get group_object_name from input record */
00499                 errn    = _getname(css, cup, buf, &c);
00500                 if (errn != 0)
00501                         goto err_eof;
00502                 _cnvrt_toupper(buf);
00503                 /* find matching group_object_name from namelist table */
00504                 if (!(fdvar = _findname(buf, nlvar, rcount))) {
00505                         if (strlen(buf) > 0) {
00506                                 /* An objectlistname in input record */
00507                                 errn    = FENLNREC;
00508                                 ERROR1(errf, css, errn, buf);
00509                         }
00510                         else {
00511                                 /* No object list name in input record */
00512                                 errn    = 0; /* empty variable entry */
00513                                 goto finalization;
00514                         }
00515                 }
00516                 /*
00517                  * c is a '%' to indicate a structure component follows.
00518                  * Look for a component name to follow the percent sign.
00519                  */
00520                 while (c == '%') {
00521                         nmlist_struclist_t *nlstruc; /* nmlist struc entry */
00522                         unsigned        scount;
00523                         nmlist_goli_t   *vaddr;
00524                         assert ((fdvar->valtype == IO_STRUC_A) || 
00525                                 (fdvar->valtype == IO_STRUC_S));
00526                         if ((fdvar->valtype == IO_SCALAR) ||
00527                             (fdvar->valtype == IO_DOPEVEC)) {
00528                                 /* structure indicator in object name
00529                                  * that is not a structure
00530                                  */
00531                                 errn    = FENLNREC;
00532                                 ERROR1(errf, css, errn, buf);
00533                         }
00534                         /* input variable is a structure */
00535                         nlstruc = fdvar->goli_addr.sptr; /* ptr to struc */
00536                         vaddr   = nlstruc->goli;        /* ptr to list */
00537                         scount  = nlstruc->structlen;   /* number entries */
00538                         /*
00539                          * Get the namelist object list name from the
00540                          * input record
00541                          */
00542                         MAINGT(c);
00543                         errn    = _getname(css, cup, buf, &c);
00544                         if (errn != 0)
00545                                 goto err_eof;
00546                         _cnvrt_toupper(buf);
00547                         /*
00548                          * Find the matching namelist object list name
00549                          * for the object list name in the input record
00550                          */
00551                         if (!(fdvar = _findname(buf, vaddr, scount))) {
00552                                 if (strlen(buf) > 0) {
00553                                         /* objectlistname in input record */
00554                                         errn    = FENLNREC;
00555                                         ERROR1(errf, css, errn, buf);
00556                                 }
00557                                 else {
00558                                         /* No name in input record */
00559                                         errn    = 0; /* empty variable entry */
00560                                         goto finalization;
00561                                 }
00562                         }
00563                 }
00564                 /* we're positioned just after the object name
00565                  * so get following value(s)
00566                  */
00567                 errn    = _getnlval(css, fdvar, &c, cup);
00568                 if (errn != 0)
00569                         goto err_eof;
00570                 sepcnt  = 0;
00571                 for ( ; ; ) {
00572                         if (!(ISBLANK(c))) {
00573                                 if ((c == ',') && (sepcnt == 0)) {
00574                                         /* skip separator */
00575                                         sepcnt++;
00576                                 }
00577                                 else
00578                                         break;
00579                         }
00580                         CMTE_MAINGT(c);
00581                 }
00582         }
00583 
00584 /***************************************************************************
00585  *      Statement Finalization Section
00586  ***************************************************************************/
00587 finalization:
00588 
00589         /* Set IOSTAT variable to 0 if no error, >0 error code otherwise */
00590         if (cilist->iostat_spec != NULL)
00591                 *cilist->iostat_spec    = errn;
00592 
00593         /* End the Beguine */
00594         STMT_END(cup, TF_READ, NULL, css);      /* Unlock unit */
00595 
00596         /* Return proper status */
00597         if (errn == 0)
00598                 return(IO_OKAY);
00599         else if (errn < 0) {
00600                 cup->pnonadv    = 0;    /* no current record if EOF */
00601                 return(IO_END);
00602         }
00603         return(IO_ERR);
00604 err_eof:
00605         /* err and eof handling */
00606         if(errn < 0) {
00607                 ENDD(endf, css, FERDPEOF);
00608         } else if (errn == FENLSTRN || errn == FENLSTRG ||
00609                    errn == FENLSUBD || errn == FENLSUBN ||
00610                    errn == FENLSUBS || errn == FENLLGNM ||
00611                    errn == FENLUNKI || errn == FENLUNKN) {
00612                         ERROR1(errf, css, errn, buf);
00613         } else {
00614                 ERROR0(errf, css, errn);
00615         }
00616         goto finalization;
00617 }
00618 
00619 /* _nlrd_fillrec - namelist read of one record from a file
00620  *      returns         0 - successful
00621  *                      EOF - end of file
00622  *                      ERR - error was encountered
00623  *                      cup->uend is set if EOF encountered
00624  */
00625 
00626 static int
00627 _nlrd_fillrec(FIOSPTR css, unit *cup)
00628 {
00629         register int    errn;
00630 
00631         errn    = css->u.fmt.endrec(css, cup, 1);
00632 
00633         return(errn);
00634 }
00635 
00636 /*
00637  *      _getname - Get variable name or group name
00638  *
00639  *      On entry:
00640  *              - Positioned to a name possibly preceded by blanks
00641  *      On exit:
00642  *              - 0 if successful
00643  *                EOF if end of file read
00644  *                > 0 if other error (errno will be set)
00645  *              - *cup->ulineptr is record position after the name.
00646  *              - *lastc contains the last character read.
00647  *      In looking for the name, we stop when we see a space, '=',
00648  *      '(', '%', or ending namelist delimiter ('&' or '$').
00649  */
00650 
00651 static int
00652 _getname(FIOSPTR css, unit *cup, char *s, char *lastc)
00653 {
00654         char    *p, c;
00655         int     n, errn;
00656         errn    = 0;
00657         n       = MAXNAML + 5; /* real*16 input can be 34 characters long */
00658         p       = s;
00659         c       = *lastc;
00660         /*
00661          * Names cannot have embedded blanks.  In cf77 compatibility mode,
00662          * a comment can immediately follow the name and terminates it.
00663          * An unknown comment character may be nonstandard for Fortran 90.
00664          * Allow the terminating ampersand for simpler non-f90 namelist
00665          * compatibility.
00666          */
00667 
00668         while (ISBLANK(c))
00669                 CMTE_SUBGTC(c);
00670         while (!(ISBLANK(c)) && c != '(' && c != '=' && c != '/' &&
00671                          c != '&' && c != '%' && c != '$') {
00672                 *p++    = c;
00673                 CMTE_SUBGTCNOEOR(c);
00674                 if (n-- == 0) {
00675                         errn    = FENLLGNM;     /* name too long */
00676                         p--;
00677                         break;
00678                 }
00679         }
00680         *lastc  = c;
00681         *p      = '\0';
00682         return (errn);
00683 }
00684 
00685 /*
00686  * _findname - find variable name in list of nmlist_goli_t entries
00687  *              of namelist table
00688  * On entry:
00689  *      - lastc points to character following name in input buffer.
00690  * Returns:
00691  *      pointer to matching object list entry
00692  *      NULL if variable name was not found.
00693  */
00694 
00695 static nmlist_goli_t
00696 *_findname(char *key, nmlist_goli_t *nlvar, unsigned countitm)
00697 {
00698         char            *varptr;
00699         unsigned        varlen;
00700         nmlist_goli_t   *newitem;
00701         int             cnt, lcnt;
00702         newitem = nlvar;
00703         cnt     = countitm;
00704         lcnt    = strlen(key);
00705         while (cnt--) {
00706                 varptr  = _fcdtocp(newitem->goli_name);
00707                 varlen  = _fcdlen(newitem->goli_name);
00708                 if ((varlen == lcnt) && (!strncmp(key, varptr, lcnt)))
00709                         return (newitem);
00710                 else {
00711                         /* cannot do this in a switch since some word32
00712                          * systems do not have the extra padding.
00713                          */
00714 #if (defined(__mips) && (_MIPS_SZLONG == 32)) || (defined(_LITTLE_ENDIAN) && !defined(_LP64))
00715                         newitem = (nmlist_goli_t*)((long *)newitem +
00716                                 3 + (sizeof(_fcd))/(sizeof(long)));
00717 #else
00718                         newitem = (nmlist_goli_t*)((long *)newitem +
00719                                 2 + (sizeof(_fcd))/(sizeof(long)));
00720 #endif
00721                 }
00722         }
00723         return (NULL);
00724 }
00725 
00726 /* _getnlval - get values for namelist io
00727  *
00728  * On entry:
00729  *      - positioned after variable name
00730  *      - lastc contains the character following the name
00731  * On exit:
00732  *      - *lastc contains the character following the value
00733  *      - cup->ulineptr is pointing to the character following lastc
00734  *      - returns: 0 if successful
00735  *                -value if EOF detected
00736  *                > 0 if error detected
00737  */
00738 
00739 static int
00740 _getnlval(FIOSPTR css, nmlist_goli_t *nlvar, char *lastc, unit *cup)
00741 {
00742         long            cntp    = 0;
00743         int             i;
00744         int             ndim    = 0;
00745         int             encnt   = 0;
00746         int             icnt    = 0;
00747         long            strbegend[3];
00748         char            *cp;
00749         char            c;
00750         long            vaddr;
00751         long            errn    = 0;
00752         struct DvDimen  dimnsn[MAXDIM];
00753         struct DvDimen  *dvdn = dimnsn;
00754         /* find offset if indexed array */
00755         /* clear array element, section, and substring information */
00756         for (i=0; i < MAXDIM; i++) {
00757                 dimnsn[i].stride_mult   = 0;
00758                 dimnsn[i].extent        = 0;
00759                 dimnsn[i].low_bound     = 0;
00760         }
00761         strbegend[0]    = -1;   /* flag indicating string */
00762         strbegend[1]    = -1;   /* string begin         */
00763         strbegend[2]    = -1;   /* string end           */
00764 
00765         switch (nlvar->valtype) {
00766         case IO_SCALAR:
00767         {
00768                 nmlist_scalar_t *nlscalar; /* nmlist scalar entry */
00769                 unsigned long   elsize;
00770                 unsigned int    int_len;
00771                 void            *vaddr;
00772                 ftype_t         type;   /* fortran data type */
00773                 nlscalar        = nlvar->goli_addr.ptr; /* ptr to scalar */
00774                 type            = nlscalar->tinfo.type;
00775                 int_len         = nlscalar->tinfo.int_len;
00776                 /* Assertions */
00777                 assert (type >= DVTYPE_TYPELESS && type <= DVTYPE_ASCII);
00778                 assert(nlscalar->tinfo.int_len > 0 );
00779                 if ((type != DVTYPE_ASCII) && (*lastc == '(')) {
00780                         errn    = FENLUNKI;
00781                         break;
00782                 }
00783                 if (type == DVTYPE_ASCII)
00784                         strbegend[0]    = 0;
00785                 if (*lastc == '(') {
00786                         errn    = _indx_nl(css, cup, dvdn, &ndim, strbegend,
00787                                 &encnt, &icnt, 0);
00788                         if (errn != 0) {
00789                                 if (errn == FENLSUBS)
00790                                         errn    = FENLSTRG;
00791                                 else if (errn == FENLSUBN)
00792                                         errn    = FENLSTRN;
00793                                 break;
00794                         }
00795                 } else {
00796                         while (ISBLANK(*lastc)) {
00797                                 CMTE_SUBGTC(*lastc);
00798                         }
00799                         /* namelist is terminated by slash, ampersand, or $ */
00800                         if ((*lastc == '/') || (*lastc == '&') || (*lastc == '$')) {
00801                                 errn    = 0;
00802                                 break;
00803                         }
00804                         /* Not a value here. */
00805                         if (*lastc != '=') {
00806                                 errn    = FENLNOVL;
00807                                 break;
00808                         }
00809                 }
00810 
00811                 /* Currently positioned after the '=' sign, but lastc is
00812                  * pointing at the '=' sign.  Update lastc for nlread and
00813                  * compute:
00814                  * cntp = number of array elements to be read
00815                  *      (1 if not an array).
00816                  * elsize = size of a variable or array element
00817                  *      (words for nonchar, bytes for char).
00818                  * vaddr = target address for input value.  For character,
00819                  *      this is a Fortran character descriptor.
00820                  */
00821                 CMTE_SUBGTC(*lastc);
00822                 if (type == DVTYPE_ASCII) {
00823                         char    *wptr;
00824                         const int bytesperchar = 1;
00825                         long    begt    = strbegend[1];
00826                         long    endt    = strbegend[2];
00827                         wptr    = _fcdtocp(nlscalar->scal_addr.charptr);
00828                         elsize  = _fcdlen(nlscalar->scal_addr.charptr);
00829                         elsize  = elsize * bytesperchar;
00830                         /* check for character substrings in input record */
00831                         if (strbegend[0] > 0) {
00832                                 if (begt < 1 )
00833                                         begt    = 1;
00834                                 else if (begt > elsize) {
00835                                         errn    = FENLUNKN;
00836                                         break;
00837                                 }
00838                                 if (endt < 1 )
00839                                         endt    = elsize;
00840                                 else if ((endt > elsize) || (endt < begt)) {
00841                                         errn    = FENLUNKN;
00842                                         break;
00843                                 }
00844                                 wptr    = wptr + (begt - 1);
00845                                 elsize  = (endt - begt) + 1;
00846                         }
00847                         vaddr   = wptr;
00848                 }
00849                 else {
00850                         vaddr   = nlscalar->scal_addr.ptr;
00851                         elsize  = int_len >> 3;
00852                 }
00853                 c       = *lastc;
00854                 cntp    = 1;
00855                 errn    = _nlread(css, type, cup, vaddr, elsize, cntp, 0, &c);
00856                 *lastc  = c;
00857                 break;
00858         }
00859         case IO_DOPEVEC:
00860         {
00861                 DopeVectorType  *nldv;
00862                 ftype_t         type;   /* fortran data type */
00863                 nldv    = nlvar->goli_addr.dv; /* ptr to dope vector */
00864                 /* Assertions */
00865                 assert ( nldv != NULL );
00866                 assert ( nldv->type_lens.int_len > 0 );
00867                 type    = nldv->type_lens.type;
00868                 if (type == DVTYPE_ASCII)
00869                         strbegend[0]    = 0;
00870                 for (i=0; i < nldv->n_dim; i++) {
00871                         dimnsn[i].stride_mult   = nldv->dimension[i].stride_mult;
00872                         dimnsn[i].extent        = nldv->dimension[i].extent;
00873                         dimnsn[i].low_bound     = nldv->dimension[i].low_bound;
00874                 }
00875                 if (*lastc == '(') {
00876                         errn    = _indx_nl(css, cup, dvdn, &ndim, strbegend,
00877                                 &encnt, &icnt, 1);
00878                         if (errn != 0)
00879                                 break;
00880                 } else {
00881                         while (ISBLANK(*lastc)) {
00882                                 CMTE_SUBGTC(*lastc);
00883                         }
00884                         /* namelist is terminated by slash, ampersand, or $ */
00885                         if ((*lastc == '/') || (*lastc == '&') || (*lastc == '$')) {
00886                                 errn    = 0;
00887                                 break;
00888                         }
00889                         /* Not a value or structure qualification here. */
00890                         if (*lastc != '=') {
00891                                 errn    = FENLNOVL;
00892                                 break;
00893                         }
00894                 }
00895 
00896                 /* Currently positioned after the '=' sign, but lastc is
00897                  * pointing at the '=' sign.  Update lastc for nlread and
00898                  * compute:
00899                  * cntp = number of array elements to be read
00900                  *      (1 if not an array).
00901                  * elsize = size of a variable or array element
00902                  *      (words for nonchar, bytes for char).
00903                  * vaddr = target address for input value.  For character,
00904                  *      this is a Fortran character descriptor.
00905                  */
00906                 CMTE_SUBGTC(*lastc);
00907                 if ((ndim != 0) && (ndim != nldv->n_dim)) {
00908                         errn    = FENLBNDY;
00909                         break;
00910                 }
00911 
00912                 /* call nlread directly for array elements. */
00913                 if (ndim != 0) {
00914                         struct DvDimen  *dvdm = nldv->dimension;
00915                         void            *vaddr;
00916                         long            extent = 1;
00917                         long            elsize;
00918                         long            mult = 1;
00919                         long            offs = 0;
00920                         long            incrmt;
00921                         int             int_len = nldv->type_lens.int_len;
00922                         register long   nc;
00923                         for (nc = 0; nc < nldv->n_dim; nc++) {
00924                                 extent *= dvdm[nc].extent;
00925                         }
00926 
00927                         /* array element. */
00928                         if (encnt == 0 && icnt == 0) {
00929                                 offs    = dimnsn[0].low_bound - (dvdm[0].low_bound);
00930                                 incrmt  = 1;
00931                                 for (nc = 1; nc < ndim; nc++) {
00932                                         mult    = mult * (dvdm[nc-1].extent);
00933                                         offs    = offs +
00934                                                ((dimnsn[nc].low_bound -
00935                                            dvdm[nc].low_bound) * mult);
00936                                 }
00937                                 extent  = extent - offs;
00938                                 if (type == DVTYPE_ASCII) {
00939                                         char            *wptr;
00940                                         const int        bytesperchar = 1;
00941                                         long    begt = strbegend[1];
00942                                         long    endt = strbegend[2];
00943                                         wptr =
00944                                           _fcdtocp(nldv->base_addr.charptr);
00945                                         elsize  =
00946                                            _fcdlen(nldv->base_addr.charptr);
00947                                         elsize  = elsize * bytesperchar;
00948                                         /* check for character
00949                                          * substrings in input record.
00950                                          */
00951                                         wptr += offs * elsize;
00952 
00953                                         if (strbegend[0] > 0) {
00954                                                 if (begt < 1 )
00955                                                         begt    = 1;
00956                                                 else if (begt > elsize) {
00957                                                         errn    = FENLUNKN;
00958                                                         break;
00959                                                 }
00960                                                 if (endt < 1 )
00961                                                         endt    = elsize;
00962                                                 else if ((endt >
00963                                                         elsize) ||
00964                                                         (endt < begt)) {
00965                                                         errn    = FENLUNKN;
00966                                                         break;
00967                                                 }
00968                                                 wptr    = wptr + (begt - 1);
00969                                                 elsize  = (endt - begt) + 1;
00970                                         }
00971 
00972                                         vaddr   = wptr;
00973                                 } else {
00974                                         bcont   *iwptr;
00975                                         iwptr   = (bcont*)nldv->base_addr.a.ptr;
00976                                         elsize  = int_len >> 3;
00977                                         iwptr  += offs * (elsize /
00978                                                 (sizeof(bcont)));
00979                                         vaddr   = iwptr;
00980                                 }
00981                                 /* Assertions */
00982                                 assert ( elsize > 0 && extent > 0 );
00983                                 c       = *lastc;
00984                                 cntp    = extent;
00985                                 errn    = _nlread(css, type, cup, vaddr,
00986                                                 elsize, cntp, incrmt, &c);
00987                                 *lastc  = c;
00988                         } else {
00989                                 for (nc = 0; nc < ndim; nc++) {
00990                                         if (dimnsn[nc].extent !=
00991                                                 dvdm[nc].extent) {
00992                                                 if (dimnsn[nc].extent >
00993                                                     dvdm[nc].extent) {
00994                                                         return(FENLBNDY);
00995                                                 }
00996                                         }
00997                                         if (dimnsn[nc].stride_mult !=
00998                                             dvdm[nc].stride_mult) {
00999                                                 dimnsn[nc].stride_mult =
01000                                                   dimnsn[nc].stride_mult *
01001                                                   dvdm[nc].stride_mult;
01002                                         }
01003                                 }
01004                                 c       = *lastc;
01005                                 errn    = _nl_stride_dv(css, cup, nldv,
01006                                                 dvdn, &c, strbegend);
01007                                 *lastc  = c;
01008                         }
01009                         
01010                 /* call nlread directly for noncharacter whole arrays */
01011                 } else if (type != DVTYPE_ASCII) {
01012                         int             n_dm = nldv->n_dim;
01013                         unsigned long   elsize = nldv->type_lens.int_len >> 3;
01014                         unsigned long   extent = nldv->dimension[0].extent;
01015                         struct DvDimen  *dvdm = nldv->dimension;
01016                         long            incrmt;
01017         
01018                         if (n_dm != 1) {
01019                                 register long   nc;
01020                                 if (n_dm == 2) {
01021                                         if (dvdm[0].stride_mult * extent !=
01022                                             dvdm[1].stride_mult)
01023                                                 goto gen_dv_process;
01024                                         extent *= dvdm[1].extent;
01025                                 } else if (n_dm == 0) {
01026                                         extent  = 1;
01027                                 } else {
01028                                         for (nc = 0; nc < (n_dm-1); nc++) {
01029                                                 register int st =
01030                                                    dvdm[nc].stride_mult;
01031                                                 register int ex =
01032                                                    dvdm[nc].extent;
01033                                                 if ( (st * ex) !=
01034                                                    dvdm[nc+1].stride_mult)
01035                                                         goto gen_dv_process;
01036                                                 extent *= dvdm[nc+1].extent;
01037                                         }
01038                                 }
01039                         }
01040                         if (extent > 1) {
01041                                 register long sm =
01042                                         nldv->dimension[0].stride_mult;
01043                                 if (sm * (signed)SMSCALE(nldv) == elsize)
01044                                         incrmt  = 1;
01045                                 else {
01046                                         int bytes_per_sm        = sm *
01047                                                 (signed)SMSCALE(nldv);
01048                                         incrmt  = bytes_per_sm / elsize;
01049                                         /* if stride not a multiple of size... */
01050                                         if (elsize * incrmt != bytes_per_sm)
01051                                                 goto gen_dv_process;
01052                                 }
01053                         } else
01054                                 incrmt  = 0;
01055 
01056                         /* Assertions */
01057                         assert ( elsize > 0 && extent > 0 );
01058                         c       = *lastc;
01059                         errn    = _nlread(css, type, cup,
01060                                         nldv->base_addr.a.ptr, elsize, extent,
01061                                         incrmt, &c);
01062                         *lastc  = c;
01063                 } else {
01064 gen_dv_process:
01065                         c       = *lastc;
01066                         errn    = _nl_stride_dv(css, cup, nldv, 0, &c, strbegend);
01067                         *lastc  = c;
01068                 }
01069                 break;
01070         }
01071         case IO_STRUC_A:
01072         {
01073                 nmlist_struclist_t *nlstruc; /* nmlist struc entry */
01074                 unsigned long   elsize;
01075                 unsigned int    int_len;
01076                 unsigned int    scount;
01077                 char            *cp;
01078                 nmlist_goli_t   *vaddr;
01079                 ftype_t         type;   /* fortran data type */
01080                 int             byt = 0; /* scalar struct has 0 offset */
01081                 nlstruc = nlvar->goli_addr.sptr; /* ptr to structure. */
01082                 vaddr   = nlstruc->goli;                /* ptr to list. */
01083                 scount  = nlstruc->structlen;   /* number of entries. */
01084                 if (*lastc == '(') {
01085                         /* This is not an array or substring - err */
01086                         errn    = FENLUNKI;
01087                         break;
01088                 } else {
01089                         while (ISBLANK(*lastc)) {
01090                                 CMTE_SUBGTC(*lastc);
01091                         }
01092                         /* namelist terminated by slash, ampersand, or $ */
01093                         if ((*lastc == '/') || (*lastc == '&') ||
01094                             (*lastc == '$')) {
01095                                 errn    = 0;
01096                                 break;
01097                         }
01098                         /* Check for structure qualification. */
01099                         if (*lastc == '%') {
01100                                 errn    = FENLIOER;
01101                                 break;
01102                         } else if (*lastc != '=') {
01103                                 errn    = FENLNOVL;
01104                                 break;
01105                         }
01106                 }
01107 
01108                 /* Currently positioned after the '=' sign, but lastc is
01109                  * pointing at the '=' sign.  Update lastc for nlread and
01110                  * compute:
01111                  * cntp = number of array elements to be read
01112                  *      (1 if not an array).
01113                  * elsize = size of a variable or array element
01114                  *      (words for nonchar, bytes for char).
01115                  * vaddr = target address for input value.  For character,
01116                  *      this is a Fortran character descriptor.
01117                  */
01118                 CMTE_SUBGTC(*lastc);
01119                 cp      = lastc;
01120                 errn    = _nlrdent(css, cup, vaddr, scount, cp, byt);
01121                 *lastc  = *cp;
01122                 break;
01123         }
01124         case IO_STRUC_S:
01125         {
01126                 nmlist_struclist_t *nlstruc; /* nmlist struc entry */
01127                 unsigned long   elsize;
01128                 unsigned int    int_len;
01129                 unsigned int    scount;
01130                 int             nc;
01131                 long            ic;
01132                 char            *cp;
01133                 long            extnt = 1;
01134                 nmlist_goli_t   *vaddr;
01135                 DopeVectorType  *nlsdv;
01136                 ftype_t         type;   /* fortran data type */
01137                 int             byt = 0; /* arraystruct offset in bytes */
01138                 unsigned int    compflag = 0;
01139                 nmlist_goli_t   *fdvar;
01140                 char            abuf[MAXNAML + 5];
01141                 nlstruc = nlvar->goli_addr.sptr; /* ptr to struc */
01142 
01143                 /* number of entries */
01144                 scount  = nlstruc->structlen;
01145 
01146                 /* ptr to list */
01147                 vaddr   = nlstruc->goli;
01148                 fdvar   = nlvar;
01149 
01150                 /* ptr to dope vector */
01151                 nlsdv   = nlstruc->struc_addr.dv;
01152                 elsize  = nlsdv->base_addr.a.el_len;
01153                 type    = nlsdv->type_lens.type;
01154 
01155                 for (i=0; i < nlsdv->n_dim; i++) {
01156                         dimnsn[i].stride_mult   = nlsdv->dimension[i].stride_mult;
01157                         dimnsn[i].extent        = nlsdv->dimension[i].extent;
01158                         dimnsn[i].low_bound     = nlsdv->dimension[i].low_bound;
01159                 }
01160                 if (*lastc == '(') {
01161                         errn    = _indx_nl(css, cup, dvdn, &ndim, strbegend,
01162                                 &encnt, &icnt, 1);
01163                         if (errn != 0)
01164                                 break;
01165                 } else {
01166                         while (ISBLANK(*lastc)) {
01167                                 CMTE_SUBGTC(*lastc);
01168                         }
01169                         /* namelist terminated by slash, ampersand, or $ */
01170                         if ((*lastc == '/') || (*lastc == '&') ||
01171                             (*lastc == '$')) {
01172                                 errn    = 0;
01173                                 break;
01174                         }
01175                 }
01176 
01177                 /* Currently positioned after the '=' sign, but lastc is
01178                  * pointing at the '=' sign.  Update lastc for nlread and
01179                  * compute:
01180                  * cntp = number of array elements to be read
01181                  *      (1 if not an array).
01182                  * elsize = size of a variable or array element
01183                  *      (words for nonchar, bytes for char).
01184                  * vaddr = target address for input value.  For character,
01185                  *      this is a Fortran character descriptor.
01186                  * 
01187                  * byt is used when the structure is an array of
01188                  * structures.  Each component must add an offset to
01189                  * its base address after the first array element.
01190                  * With derived types, the bits must be changed to bytes.
01191                  */
01192                 CMTE_SUBGTC(*lastc);
01193                 if ((ndim != 0) && (ndim != nlsdv->n_dim)) {
01194                         errn    = FENLBNDY;
01195                         break;
01196                 }
01197                 /* Check for structure qualification. */
01198                 while (*lastc == '%') {
01199                         compflag++;
01200                         nlstruc = fdvar->goli_addr.sptr;
01201                         vaddr   = nlstruc->goli;
01202                         scount  = nlstruc->structlen;
01203                         /* Check for structure qualification. */
01204                         SUBGTC(*lastc);
01205                         errn    = _getname(css, cup, abuf, lastc);
01206                         if (errn != 0)
01207                                 break;
01208                         _cnvrt_toupper(abuf);
01209                         /* find matching namelist object list
01210                         * name in input record
01211                         */
01212                         if (!(fdvar = _findname(abuf, vaddr, scount))) {
01213                                 if (strlen(abuf) > 0) {
01214                                 /* objectlistname in record */
01215                                         errn    = FENLNREC;
01216                                         break;
01217                                 } else {
01218                                 /* no name in record. May be
01219                                  * empty record. Quit process.
01220                                  */
01221                                 errn    = 0;
01222                                 break;
01223                                 }
01224                         } else
01225                                 vaddr   = fdvar;
01226                         while (ISBLANK(*lastc)) {
01227                                 CMTE_SUBGTC(*lastc);
01228                         }
01229                         if (*lastc != '=') {
01230                                 errn    = FENLNOVL;
01231                                 break;
01232                         }
01233                         CMTE_SUBGTC(*lastc);
01234                 }
01235                 if (ndim != 0) {
01236                         struct DvDimen  *dvdm = nlsdv->dimension;
01237                         long            mult = 1;
01238                         long            offs = 0;
01239                         register long   nc;
01240                         for (nc = 0; nc < nlsdv->n_dim; nc++)
01241                                 extnt *= nlsdv->dimension[nc].extent;
01242                         /* array element. */
01243                         if (encnt == 0 && icnt == 0) {
01244                                 offs    = dimnsn[0].low_bound - (dvdm[0].low_bound);
01245                                 for (nc = 1; nc < ndim; nc++) {
01246                                         mult    = mult * (dvdm[nc-1].extent);
01247                                         offs    = offs +
01248                                            ((dimnsn[nc].low_bound -
01249                                            dvdm[nc].low_bound) * mult); 
01250                                 }
01251                                 extnt   = extnt - offs;
01252                                 elsize  = elsize >> 3;
01253                                 byt     = offs * elsize;
01254                                 assert ( elsize > 0 && extnt > 0);
01255                                 cp      = lastc;
01256                                 if (compflag)
01257                                         scount  = 1;
01258                                 errn    = _nlrdent(css, cup, vaddr, scount,
01259                                                 cp, byt);
01260                                 *lastc  = *cp;
01261                         } else {
01262                                 for (nc = 0; nc < ndim; nc++) {
01263                                         if (dimnsn[nc].extent !=
01264                                             dvdm[nc].extent) {
01265                                                 if (dimnsn[nc].extent >
01266                                                    dvdm[nc].extent) {
01267                                                         return(FENLBNDY);
01268                                                 }
01269                                         }
01270                                         if (dimnsn[nc].stride_mult !=
01271                                            dvdm[nc].stride_mult) {
01272                                                 dimnsn[nc].stride_mult =
01273                                                    dimnsn[nc].stride_mult *
01274                                                    dvdm[nc].stride_mult;
01275                                         }
01276                                 }
01277                                 cp      = lastc;
01278                                 if (compflag)
01279                                         scount  = 1;
01280                                 errn    = _nl_strd_derv(css, cup, nlsdv, dvdn,
01281                                                 cp, vaddr, scount, byt);
01282                                 *lastc  = *cp;
01283                         }
01284                 } else {
01285                         cp      = lastc;
01286                         errn    = _nl_strd_derv(css, cup, nlsdv, 0, cp,
01287                                         vaddr, scount, byt);
01288                         *lastc  = *cp;
01289                 }
01290                 break;
01291         }
01292         default:
01293                  errn   = FEINTUNK;
01294         }
01295         return(errn);
01296 }
01297 
01298 /*      _nlread - calls _nexdata to get the next value and stores the
01299  *              result in the namelist object entry.
01300  *      On Entry - cup_ulineptr points to the first character following the
01301  *              value.
01302  *      On Exit - lastc  will contain the first nonblank, nonseparator
01303  *              character following the value.
01304  */
01305 
01306 static int
01307 _nlread(FIOSPTR css, ftype_t type, unit *cup, void *ptr, long elsize,
01308         int cntp, int incrm, char *lastc)
01309 {
01310         long            ss, ncntp;
01311         long            stat;
01312         char            c;
01313         void            *vaddr;
01314         long            errn = 0;
01315         int             lcount;         /* repeat count for values */
01316         long            lval[9];        /* convert space */
01317         bcont           *sval;
01318         int             nullvlu;
01319         c       = *lastc;
01320         ncntp   = cntp;
01321         vaddr   = ptr;
01322         nullvlu = 0;
01323 
01324         while (ncntp > 0) {
01325                 errn    = _nexdata(css, type, vaddr, ncntp, 1, c, cup,
01326                                 lval, &lcount, elsize, &nullvlu);
01327                 if (errn != 0)
01328                         return(errn);
01329                 else {
01330                         if (nullvlu == 2) {
01331                                 lcount  = 0;
01332                                 ncntp   = 0;
01333                         }
01334                 }
01335                 if (lcount > ncntp) {
01336                         errn    = FENLTOOM;
01337                         return(errn);
01338                 }
01339                 if (type == DVTYPE_ASCII) {
01340                         char    *wptr;
01341                         wptr    = vaddr;
01342                         /* character data already stored, adjust
01343                          * ptr and count only.
01344                          */
01345                         ncntp   = ncntp - lcount;
01346                         wptr    = wptr + (lcount * elsize);
01347                         vaddr   = wptr;
01348                 }
01349                 else {
01350                         int move;
01351                         int *iptr;
01352                         int ix, lim;
01353                         bcont *siptr;
01354                         move    = MIN(ncntp,lcount);
01355                         lim     = elsize/(sizeof(bcont));
01356                         siptr   = (bcont*) vaddr;
01357                         /* move what's needed from data group */
01358                         while (move != 0) {
01359                                 sval    = (bcont*) lval;
01360                                 /* do not move null values */
01361                                 if (!nullvlu) {
01362                                         for (ix=0; ix < lim; ix++) {
01363                                                 *siptr  = *sval;
01364                                                 siptr++;
01365                                                 sval++;
01366                                         }
01367                                 } else
01368                                         siptr   = siptr + lim;
01369                                 vaddr   = siptr;
01370                                 move--;
01371                                 ncntp--;
01372                                 lcount--;
01373                         }
01374                 }
01375                 do {
01376                         CMTE_SUBGTC(*lastc);
01377                 } while (ISBLANK(*lastc));
01378                 if (*lastc == ',') {
01379                         do {
01380                                 CMTE_SUBGTC(*lastc);
01381                         } while (ISBLANK(*lastc));
01382                 }
01383         c       = *lastc;
01384         }
01385         return(0);
01386 }
01387 
01388 /*      _indx_nl        compute the dimension information of an
01389  *                      indexed array in the input record.
01390  *      On entry:
01391  *              _ positioned just after the '('
01392  *      On exit:
01393  *              - returns:      0 on success
01394  *                              -value on eof
01395  *              - positioned just after the '='
01396  *              - if % occurred, the scan is backed up one
01397  *              - the lastc argument is not changed
01398  */
01399 
01400 static int
01401 _indx_nl(
01402         FIOSPTR css, unit *cup, struct DvDimen *dvdn, int *ndima,
01403         long strbegend[3],int *encnt, int *icnt, int arryflag)
01404 {
01405         long    mode, ss;
01406         long    offs, mult;
01407         char    c;
01408         int     i, j, ir1, en1;
01409         long    dummy;
01410         int     errn = 0;
01411         long    stat;
01412         long    field_width;
01413         long    *field_begin;
01414         long    *field_end;
01415         long    tempbuf[2];
01416         en1     = 0;
01417         ir1     = 0;
01418         if (arryflag) {
01419                 for (i = 0; i < MAXDIMS; ) {
01420                         long    dummy;
01421                         /* no comments in namelist input here and
01422                          * skip leading blanks here only. 
01423                          */
01424                         do {
01425                                 SUBGTC(c);
01426                         } while (ISBLANK(c));
01427                         /* Was end of subscripts reached in input record */
01428                         if (c == ')')
01429                                 break;
01430                         cup->ulinecnt++;
01431                         cup->ulineptr--;
01432 
01433                         /* Get the low_bound subscript information first */
01434                         GETSECTION(c);
01435                         if (field_width == 0)
01436                                 goto indxgetext;
01437                         /* pass field_end + 1 */
01438                         field_end++;
01439                         tempbuf[0]      = 0;
01440                         tempbuf[1]      = 0;
01441                         mode            = 0;
01442                         (void) _iu2s(field_begin, &field_width,
01443                                 &field_end, &mode, tempbuf, &stat,
01444                                 &dummy, &dummy);
01445                         if(stat < 0) {
01446                                 errn    = FENLSUBS;
01447                                 return(errn);
01448                         }
01449                         dvdn[i].low_bound       = *((_f_int8 *)tempbuf);
01450 indxgetext:
01451                         /* point beyond subscript or lowbound. */
01452                         cup->ulineptr   = field_begin + field_width;
01453                         cup->ulinecnt   = cup->ulinecnt - field_width;
01454 
01455                         /* Get extent subscript information */
01456                         if (c == ':') {
01457                                 /* update ulineptr */
01458                                 SUBGTC(c);
01459                                 GETSECTION(c);
01460                                 if (field_width == 0)
01461                                         goto indxgetinc;
01462                                 /* pass field_end + 1 */
01463                                 field_end++;
01464                                 tempbuf[0]      = 0;
01465                                 tempbuf[1]      = 0;
01466                                 mode            = 0;
01467                                 (void) _iu2s(field_begin, &field_width,
01468                                         &field_end, &mode, tempbuf, &stat,
01469                                         &dummy, &dummy);
01470                                 if(stat < 0) {
01471                                         errn    = FENLSUBS;
01472                                         return(errn);
01473                                 }
01474                                 /* calculate extent from upper bound
01475                                  * (upperbound - lowerbound) + 1
01476                                  */
01477                                 dvdn[i].extent  = (*((_f_int8 *)tempbuf) -
01478                                                    dvdn[i].low_bound) + 1;
01479                                 en1++;
01480 indxgetinc:
01481                                 /* point beyond subscript extent. */
01482                                 cup->ulineptr   = field_begin + field_width;
01483                                 cup->ulinecnt   = cup->ulinecnt - field_width;
01484 
01485                                 /* Get stride_mult subscript information */
01486                                 if (c == ':') {
01487                                         /* update ulineptr */
01488                                         SUBGTC(c);
01489                                         GETSECTION(c);
01490                                         if (field_width == 0)
01491                                                 goto indxforloop;
01492                                         /* pass field_end + 1 */
01493                                         field_end++;
01494                                         tempbuf[0]      = 0;
01495                                         tempbuf[1]      = 0;
01496                                         mode            = 0;
01497                                         (void) _iu2s(field_begin,
01498                                                 &field_width, &field_end,
01499                                                 &mode, tempbuf, &stat,
01500                                                 &dummy, &dummy);
01501                                         if(stat < 0) {
01502                                                 errn    = FENLSUBS;
01503                                                 return(errn);
01504                                         }
01505                                         dvdn[i].stride_mult     = *((_f_int8 *)tempbuf);
01506                                         ir1++;
01507 indxforloop:
01508                                         /* point beyond subscript stride_mult. */
01509                                         cup->ulineptr   = field_begin + field_width;
01510                                         cup->ulinecnt   = cup->ulinecnt - field_width;
01511                                 }
01512                         }
01513                         /* increment the number of subscripts */
01514                         i++;
01515                         do {
01516                                 SUBGTC(c);      /* get to ',' or ')' */
01517                         } while (ISBLANK(c));   /* NO EOR allowed here */
01518                         /* check for end of subscripts */
01519                         if (c == ')')
01520                                 break;
01521                         if (c != ',') {
01522                                 errn    = FENLSUBD;     /* Not a comma */
01523                                 return(errn);
01524                         }
01525                 }
01526                 *ndima  = i;
01527                 *encnt  = en1;
01528                 *icnt   = ir1;
01529                 if (i == 0) {
01530                         errn    = FENLSUBN;     /* null index */
01531                         return(errn);
01532                 }
01533         }
01534         if (strbegend[0] == 0) {
01535                 j       = 0;
01536                 if (arryflag) {
01537                         SUBGTC(c);
01538                 } else
01539                         c       = '(';
01540                 /* Check for substring information after array element */
01541                 if (c == '(') {
01542                         /* skip leading blanks in input here */
01543                         do {
01544                                 SUBGTC(c);
01545                         } while (ISBLANK(c));
01546                         /* End of subscripts found in input record? */
01547                         if (c == ')') {
01548                                 errn    = FENLSTRN;     /* null index */
01549                                 return(errn);
01550                         }
01551                         cup->ulinecnt++;
01552                         cup->ulineptr--;
01553                         GETSECTION(c);
01554                         if (field_width == 0)
01555                                 goto indxstrend;
01556                         /* pass field_end + 1 */
01557                         field_end++;
01558                         tempbuf[0]      = 0;
01559                         tempbuf[1]      = 0;
01560                         mode            = 0;
01561                         (void) _iu2s(field_begin, &field_width, &field_end,
01562                                 &mode, tempbuf, &stat, &dummy, &dummy);
01563                         if(stat < 0) {
01564                                 errn    = FENLSTRG;
01565                                 return(errn);
01566                         }
01567                         strbegend[1]    = *((_f_int8 *)tempbuf);
01568                         j++;
01569 indxstrend:
01570                         /* point beyond colon. */
01571                         cup->ulineptr   = field_begin + field_width;
01572                         cup->ulinecnt   = cup->ulinecnt - field_width;
01573                         if (c == ':') {
01574                                 /* update ulineptr */
01575                                 SUBGTC(c);
01576                                 /* skip leading blanks in input here */
01577                                 do {
01578                                         SUBGTC(c);
01579                                 } while (ISBLANK(c));
01580                                 /* End of subscripts found in input rec */
01581                                 if (c == ')')
01582                                         goto indxstrout;
01583                                 cup->ulinecnt++;
01584                                 cup->ulineptr--;
01585                                 GETSECTION(c);
01586                                 if (field_width == 0)
01587                                         goto indxstrdon;
01588                                 /* pass field_end + 1 */
01589                                 field_end++;
01590                                 tempbuf[0]      = 0;
01591                                 tempbuf[1]      = 0;
01592                                 mode            = 0;
01593                                 (void) _iu2s(field_begin, &field_width,
01594                                         &field_end, &mode, tempbuf,
01595                                         &stat, &dummy, &dummy);
01596                                 if(stat < 0) {
01597                                         errn    = FENLSTRG;
01598                                         return(errn);
01599                                 }
01600                                 strbegend[2]    = *((_f_int8 *)tempbuf);
01601                                 j++;
01602 indxstrdon:
01603                                 /* point to right paren? */
01604                                 cup->ulineptr   = field_begin + field_width;
01605                                 cup->ulinecnt   = cup->ulinecnt - field_width;
01606                         }
01607 indxstrout:
01608                         strbegend[0]    = j;
01609                 }
01610         }
01611         /*
01612          * Look for the equal sign or the structure qualification
01613          * character
01614          */
01615         while (!(c == '=') && !(c == '%')) {
01616                 SUBGTC(c);
01617         }
01618         if (c == '%') {
01619                 cup->ulineptr--;
01620                 cup->ulinecnt++;
01621         }
01622         return(errn);
01623 }
01624 
01625 /* Converts the string in buf to upper case letters */
01626 
01627 static void
01628 _cnvrt_toupper(char *buf)
01629 {
01630         char    c;
01631         while ((c = *buf) != '\0') {
01632                 *buf++  = toupper(c);
01633         }
01634         return;
01635 }
01636 
01637 /*
01638  *      _nlrdent - namelist input of structure entries
01639  *              Recursive call to handle structure table entries for
01640  *              namelist.
01641  *      Return value:
01642  *              0 on success.  lval contains result.
01643  *                      lcount contains repeat count.
01644  *              >0 error code if error encountered
01645  */
01646 
01647 static int
01648 _nlrdent(FIOSPTR css, unit *cup, nmlist_goli_t *nalist, unsigned count,
01649         char *lastc, int byt)
01650 {
01651         char    c, oc;
01652         int     ocnt, ss;
01653         long    *optr;
01654         unsigned        scnt;   /* count of namelist struc items */
01655         nmlist_goli_t   *nlvar; /* ptr to NEXT Var entry */
01656         int             errn;   /* error number */
01657         int             cntp;
01658         c       = *lastc;
01659         scnt    = count;
01660         errn    = 0;
01661         nlvar   = nalist;       /* group object pointer */
01662 
01663         while (scnt--) {
01664                 switch(nlvar->valtype) {
01665                 case IO_SCALAR:
01666                 {
01667                         nmlist_scalar_t *nlscalar; /* nmlist scalar entry */
01668                         unsigned long   elsize;
01669                         unsigned int    int_len;
01670                         void            *vaddr;
01671                         ftype_t         type;   /* fortran data type */
01672                         int             adj = 0;
01673                         cntp    = 1;
01674                         nlscalar = nlvar->goli_addr.ptr; /* ptr to scalar */
01675                         type    = nlscalar->tinfo.type;
01676                         int_len = nlscalar->tinfo.int_len;
01677                         /* Assertions */
01678                         assert (type >= DVTYPE_TYPELESS &&
01679                                         type <= DVTYPE_ASCII);
01680                         assert(nlscalar->tinfo.int_len > 0 );
01681                         if (type == DVTYPE_ASCII) {
01682                                 char    *wptr;
01683                                 const int bytesperchar = 1;
01684                                 wptr =
01685                                    _fcdtocp(nlscalar->scal_addr.charptr) +
01686                                    byt;
01687                                 elsize =
01688                                    _fcdlen(nlscalar->scal_addr.charptr);
01689                                 elsize  = elsize * bytesperchar;
01690                                 /* Any character substring in input record */
01691                                 vaddr   = wptr;
01692                         }
01693                         else {
01694                                 if (byt > 0)
01695                                         adj     = byt/(sizeof(bcont));
01696                                 vaddr   = ((bcont*)nlscalar->scal_addr.ptr) +
01697                                                 adj;
01698                                 elsize  = int_len >> 3;
01699                         }
01700                         errn    = _nlread(css, type, cup, vaddr, elsize,
01701                                         cntp, 0, &c);
01702                         if (errn != 0)
01703                                 return(errn);
01704                         *lastc  = c;
01705                         break;
01706                 }
01707                 case IO_DOPEVEC:
01708                 {
01709                         DopeVectorType  *nldv;
01710                         unsigned long   elsize;
01711                         unsigned long   extent = 1;
01712                         unsigned int    int_len;
01713                         void            *vaddr;
01714                         int             nc;
01715                         ftype_t         type;   /* fortran data type */
01716                         int             adj = 0;
01717                         nldv    = nlvar->goli_addr.dv; /* ptr to dope vector */
01718                         /* Assertions */
01719                         assert ( nldv != NULL );
01720                         assert ( nldv->type_lens.int_len > 0 );
01721                         type    = nldv->type_lens.type;
01722                         int_len = nldv->type_lens.int_len;
01723                         if (type == DVTYPE_ASCII) {
01724                                 char    *wptr;
01725                                 const int       bytesperchar = 1;
01726                                 wptr    = _fcdtocp(nldv->base_addr.charptr) +
01727                                         byt;
01728                                 elsize  = _fcdlen(nldv->base_addr.charptr);
01729                                 elsize  = elsize * bytesperchar;
01730                                 vaddr   = wptr;
01731                         }
01732                         else {
01733                                 if (byt > 0)
01734                                         adj     = byt/(sizeof(bcont));
01735                                 vaddr   = ((bcont*)nldv->base_addr.a.ptr) + adj;
01736                                 elsize  = int_len >> 3;
01737                         }
01738                         for (nc = 0; nc < nldv->n_dim; nc++) {
01739                                 extent *= nldv->dimension[nc].extent;
01740                         }
01741                         /* Assertions */
01742                         assert ( elsize > 0 && extent > 0 );
01743                         cntp    = extent;
01744                         errn    = _nlread(css, type, cup, vaddr, elsize,
01745                                         cntp, 1, &c);
01746                         if (errn != 0)
01747                                 return(errn);
01748                         *lastc  = c;
01749                         break;
01750                 }
01751                 case IO_STRUC_A:
01752                 {
01753                         nmlist_struclist_t *nlstruc; /* nmlist struc entry */
01754                         unsigned long   elsize;
01755                         unsigned int    int_len;
01756                         unsigned int    scount;
01757                         nmlist_goli_t   *vaddr;
01758                         ftype_t         type;   /* fortran data type */
01759                         int             bytoff;
01760                         nlstruc = nlvar->goli_addr.sptr; /* ptr to struc */
01761                         scount  = nlstruc->structlen;   /* number entries */
01762                         vaddr   = nlstruc->goli;        /* ptr to list */
01763                         /*
01764                          * No additional offset needed, pass current
01765                          * offset on to next version.
01766                          */
01767                         bytoff  = byt;
01768                         errn =
01769                            _nlrdent(css, cup, vaddr, scount, &c, bytoff);
01770                         if (errn != 0)
01771                                 return(errn);
01772                         *lastc  = c;
01773                         break;
01774                 }
01775                 case IO_STRUC_S:
01776                 {
01777                         nmlist_struclist_t *nlstruc; /* nmlist struc entry */
01778                         unsigned long   elsize;
01779                         unsigned int    int_len;
01780                         unsigned int    scount;
01781                         int             nc;
01782                         long            ic;
01783                         long            extnt=1;
01784                         nmlist_goli_t   *vaddr;
01785                         DopeVectorType  *nlsdv;
01786                         ftype_t         type;   /* fortran data type */
01787                         int             bytoff;
01788                         nlstruc = nlvar->goli_addr.sptr; /* ptr to struc */
01789                         scount  = nlstruc->structlen;   /* number entries */
01790                         vaddr   = nlstruc->goli;        /* ptr to list */
01791                         nlsdv   = nlstruc->struc_addr.dv; /* ptr to dopevec */
01792                         /*
01793                          * byt is used when the structure is an array
01794                          * of structures.  Each element must add an offset
01795                          * to its address after the first array element.
01796                          */
01797                         elsize  = nlsdv->base_addr.a.el_len;
01798                         for (nc = 0; nc < nlsdv->n_dim; nc++) {
01799                                 extnt *= nlsdv->dimension[nc].extent;
01800                         }
01801                         for (ic = 0; ic < extnt; ic++) {
01802                                 /*
01803                                  * create another byte offset for this
01804                                  * nesting of a structure of arrays.  Must
01805                                  * change elsize from bits to bytes.
01806                                  */
01807                                 bytoff  = byt + ((elsize >> 3) * ic);
01808                                 errn    = _nlrdent(css, cup, vaddr, scount,
01809                                         &c, bytoff);
01810                                 if (errn != 0)
01811                                         return(errn);
01812                         }
01813                         *lastc  = c;
01814                         break;
01815                 }
01816                 default:
01817                         errn    = FEINTUNK;
01818                 }
01819                 if (errn !=0)
01820                         return(errn);
01821 #if (defined(__mips) && (_MIPS_SZLONG == 32)) || (defined(_LITTLE_ENDIAN) && !defined(_LP64))
01822                 nlvar   = (nmlist_goli_t*)((long *)nlvar + 3 +
01823                         (sizeof(_fcd))/(sizeof(long)));
01824 #else
01825                 nlvar   = (nmlist_goli_t*)((long *)nlvar + 2 +
01826                         (sizeof(_fcd))/(sizeof(long)));
01827 #endif
01828         }
01829         return(errn);
01830 }
01831 
01832 /*      _nexdata - get the next data group - position at the first character
01833  *              following the value or values.
01834  *      On return, lval will contain the value and lcount the repeat count
01835  *      Outptr will point to character immediately following value
01836  *
01837  *      The return value is:    -value for EOF
01838  *                              0 for ok
01839  *                              >0 if an error
01840  *              nullvlu =       1 for null value read
01841  *                              2 for null value, followed by possible
01842  *                                variable name
01843  */
01844 static int
01845 _nexdata(
01846         FIOSPTR         css,
01847         ftype_t         type,   /* Type of data item */
01848         void            *ptr,   /* Address of data item */
01849         int             cnt,    /* Number of values to look for */
01850         int             inc,
01851         char            lastc,  /* First character of value, may be blank */
01852         unit            *cup,   /* Input unit */
01853         long            *lval,  /* Value is placed here */
01854         int             *lcount, /* Repeat count is returned here */
01855         long            elsize,
01856         int             *nullvlu) /* indicate if any nulls returned */
01857 {
01858         char    c, oc;
01859         int     ocnt;
01860         long    *optr;
01861         int     holcnt;         /* Length of hollerith string */
01862         char    newc;
01863         int     errn;
01864         *nullvlu        = 0;
01865         c       = lastc;
01866         while (ISBLANK(c)) {
01867                 CMTE_SUBGTC(c);
01868         }
01869         *lcount = 1;    /* set repeat count */
01870         if (isdigit((int) c)) {
01871                 /* Look for repeat count.  We can have a repeat count
01872                  * for any type of data, including character.
01873                  */
01874                 *lcount = c - '0';
01875                 ocnt    = cup->ulinecnt; /* save count and pointer, in case */
01876                 optr    = cup->ulineptr; /* this isn't repeat count */
01877                 oc      = c;
01878                 for (;;) {
01879                         /* get next character */
01880                         /* blank character if end-of-record */
01881                         SUBGTCNOEOR(c);
01882                         if (isdigit((int) c))
01883                                 *lcount = (*lcount * 10) + c - '0';
01884                         else
01885                                 break;
01886                 }
01887                 /*
01888                  * Could have r*c, rH, rL, or rR, where r is the number just
01889                  * read.  No embedded blanks allowed in r*c, rH, rL, or rR.
01890                  */
01891                 switch (c) {
01892                 case '*':
01893                         /* get next character */
01894                         /* blank character if end-of-record */
01895                         CMTE_SUBGTCNOEOR(c);
01896                         if (isdigit((int) c)) {
01897                                 /* See if we have a repeat count followed
01898                                  * by hollerith, like 3*4Habcd
01899                                  */
01900                                 holcnt  = c - '0';
01901                                 ocnt    = cup->ulinecnt;
01902                                 optr    = cup->ulineptr;
01903                                 oc      = c;
01904                                 for (;;) {
01905                                         /* blank character if end-of-record */
01906                                         SUBGTCNOEOR(c);
01907                                         if (isdigit((int) c))
01908                                                 holcnt  = (holcnt * 10) +
01909                                                         c - '0';
01910                                         else
01911                                                 break;
01912                                 }
01913                                 switch (c) {
01914                                 case 'H':
01915                                 case 'h':
01916                                 case 'R':
01917                                 case 'r':
01918                                 case 'L':
01919                                 case 'l':
01920                                         return(_get_holl(css, cup, c, holcnt,
01921                                                 type, lval, elsize));
01922                                 default:
01923                                         /* backup restore */
01924                                         cup->ulineptr   = optr;
01925                                         /* cnt and ptr */
01926                                         cup->ulinecnt   = ocnt;
01927                                         c       = oc;
01928                                         ocnt    = 1;
01929                                         break;
01930                                 } /* switch */
01931                         }
01932                         break;  /* Ordinary repeat count */
01933                 case 'H':
01934                 case 'h':
01935                 case 'R':
01936                 case 'r':
01937                 case 'L':
01938                 case 'l':
01939                 /* Assume it is a Hollerith string, like 3Habc */
01940                         holcnt  = *lcount;
01941                         *lcount = 1;    /* No repeats */
01942                         return(_get_holl(css, cup, c, holcnt, type,
01943                                 lval, elsize));
01944                 default:
01945                         /* No repeat count, backup restore, cnt & ptr */
01946                         cup->ulineptr   = optr;
01947                         cup->ulinecnt   = ocnt;
01948                         c               = oc;
01949                         ocnt            = 1;
01950                         *lcount         = 1;
01951                         break;
01952                 } /* switch */
01953         }
01954         /* END of isdigit()
01955          * Looking for a value.  When we get here we are at a nonblank
01956          * character, unless we had the form r*, in which case it may
01957          * be followed by a blank (NULL).
01958          */
01959         if (c == ',') {
01960                 cup->ulineptr--; /* reset cnt and ptr so */
01961                 cup->ulinecnt++; /* we can read separator again */
01962                 *nullvlu        = 1;
01963                 return(0);      /* return null value */
01964         }
01965         else if (ISBLANK(c)) {
01966                 *nullvlu        = 1;
01967                 return(0);      /* return null value */
01968         }
01969         else {
01970                 if (c == '!') {
01971                         /* use this path with input like:  a = 5,!comment */
01972                         cup->ulineptr--; /* reset cnt and ptr so */
01973                         cup->ulinecnt++; /* we can read separator again */
01974                         *nullvlu        = 1;
01975                         return(0);      /* return null value */
01976                 } else
01977                         if (c == '/' || c == '&' || c == '$') {
01978                                 /* treated terminating slash or ampersand
01979                                  * the same for f90 to allow simpler
01980                                  * non-f90 compatibility.
01981                                  */
01982                                 cup->ulineptr--; /* reset cnt and ptr so */
01983                                 cup->ulinecnt++; /* read delimiter again */
01984                                 *nullvlu        = 2;
01985                                 return(0);      /* Return null value */
01986                         }
01987         }
01988         /*
01989          * It is important that we handle the special cases of types logical
01990          * and character first, because the format of their data is treated
01991          * differently.
01992          */
01993         if (type == DVTYPE_LOGICAL) {
01994                 bcont   *slval;
01995                 slval   = (bcont *)lval;
01996 
01997                 /* Looking for a logical value.  Logical values must be of
01998                  * the form: optional decimal point, followed by a 'T' for
01999                  * true or an 'F' for false, optionally followed by one
02000                  * or more additional characters.  Those additional
02001                  * characters cannot include '=', ',', ':', ';', '(', '$'
02002                  * or '&'.
02003                  */
02004                 if (c == '.') {
02005                         /* blank character if end-of-record */
02006                         SUBGTCNOEOR(c);
02007                         /* .T or .t assumed to be a logical value */
02008                         if ((c == 'T') || (c == 't')) {
02009                                 switch (elsize) {
02010 #ifdef _F_INT4
02011                                 case 4:
02012                                         *(_f_log4 *)slval       = _btol(1);
02013                                         break;
02014 #if     defined(_F_INT2) && (defined(__mips) || defined(__sv2))
02015                                 case 2:
02016                                         *(_f_log2 *)slval       = _btol(1);
02017                                         break;
02018                                 case 1:
02019                                         *(_f_log1 *)slval       = _btol(1);
02020                                         break;
02021 #endif  /* _F_INT2 and (mips or sv2) */
02022 #endif  /* _F_INT4 */
02023                                 case 8:
02024                                         *(_f_log8 *)slval       = _btol(1);
02025                                         break;
02026                                 default:
02027                                         return(FEKNTSUP); /* kind not supported */
02028                                 }
02029 
02030                         /* F and .f are assumed to be a logical value */
02031                         } else if ((c == 'F') || (c == 'f')) {
02032                                 switch (elsize) {
02033 #ifdef _F_INT4
02034                                 case 4:
02035                                         *(_f_log4 *)slval       = _btol(0);
02036                                         break;
02037 #if     defined(_F_INT2) && (defined(__mips) || defined(__sv2))
02038                                 case 2:
02039                                         *(_f_log2 *)slval       = _btol(0);
02040                                         break;
02041                                 case 1:
02042                                         *(_f_log1 *)slval       = _btol(0);
02043                                         break;
02044 #endif  /* _F_INT2 and (mips or sv2) */
02045 #endif  /* _F_INT4 */
02046                                 case 8:
02047                                         *(_f_log8 *)slval       = _btol(0);
02048                                         break;
02049                                 default:
02050                                         return(FEKNTSUP); /* kind not supported */
02051                                 }
02052                         } else {
02053                                 errn    = FENLIVLG;     /* Invalid logical */
02054                                 return(errn);
02055                         }
02056                 }
02057                 else {
02058                         /* If the string does not start with a '.', it could
02059                          * be a logical value or a variable name.  Try to
02060                          * determine which by seeing if it is followed by a
02061                          * replacement character or '('.  Save count and
02062                          * pointer in case this isn't a value.
02063                          */
02064                         ocnt    = cup->ulinecnt;
02065                         optr    = cup->ulineptr;
02066                         /* do not go beyond the end of the buffer */
02067                         if (ocnt > 0) {
02068                                 newc    = *optr++;
02069                                 ocnt--;
02070                                 while (!(ISBLANK(newc))) {
02071                                 /* check for terminating or separator char */
02072                                         if (newc == ',' || newc == '/' ||
02073                                             newc == '&' || newc == '$')
02074                                                 break;
02075                                         if ((newc == '=') || (newc == '(') ||
02076                                             (newc == '%')) {
02077                                         /* Reset, this MAY be the first
02078                                          * letter of a variable name
02079                                          */
02080                                                 cup->ulineptr--;
02081                                                 cup->ulinecnt++;
02082                                                 *nullvlu        = 2;
02083                                                 return(0); /* Null value */
02084                                         }
02085                                         if (ocnt <= 0)
02086                                                 break;
02087                                         newc    = *optr++;
02088                                         ocnt--;
02089                                 }
02090                                 while ((ISBLANK(newc)) && ocnt-- > 0)
02091                                         newc    = *optr++;
02092                                 if (newc == '=') {
02093                                 /*
02094                                  * Reset, because this MAY have been
02095                                  * the first letter of a variable name
02096                                  */
02097                                         cup->ulineptr--;
02098                                         cup->ulinecnt++;
02099                                         *nullvlu        = 2;
02100                                         return(0);      /* Null value */
02101                                 }
02102                         }
02103                         if ((c == 'T') || (c == 't')) {
02104                                 switch (elsize) {
02105 #ifdef _F_REAL4
02106                                 case 4:
02107                                         *(_f_log4 *)slval       = _btol(1);
02108                                         break;
02109 #if     defined(_F_INT2) && (defined(__mips) || defined(__sv2))
02110                                 case 2:
02111                                         *(_f_log2 *)slval       = _btol(1);
02112                                         break;
02113                                 case 1:
02114                                         *(_f_log1 *)slval       = _btol(1);
02115                                         break;
02116 #endif  /* _F_INT2 and (mips or sv2) */
02117 #endif
02118                                 case 8:
02119                                         *(_f_log8 *)slval       = _btol(1);
02120                                         break;
02121                                 default:
02122                                         return(FEKNTSUP); /* kind not supported */
02123                                 }
02124                         }
02125                         else if ((c == 'F') || (c == 'f')) {
02126                                 switch (elsize) {
02127 #ifdef _F_REAL4
02128                                 case 4:
02129                                         *(_f_log4 *)slval       = _btol(0);
02130                                         break;
02131 #if     defined(_F_INT2) && (defined(__mips) || defined(__sv2))
02132                                 case 2:
02133                                         *(_f_log2 *)slval       = _btol(0);
02134                                         break;
02135                                 case 1:
02136                                         *(_f_log1 *)slval       = _btol(0);
02137                                         break;
02138 #endif  /* _F_INT2 and (mips or sv2) */
02139 #endif
02140                                 case 8:
02141                                         *(_f_log8 *)slval       = _btol(0);
02142                                         break;
02143                                 default:
02144                                         return(FEKNTSUP); /* kind not supported */
02145                                 }
02146                         }
02147                         else if (ISBLANK(c) || c == ',') {
02148                                 *nullvlu        = 1;
02149                                 return(0);      /* Indicate null value */
02150                         }
02151                         else {
02152                                 errn    = FENLIVLG;     /* Invalid logical */
02153                                 return(errn);
02154                         }
02155                 }
02156                 /* We assume we're reading a logical value.
02157                  * Skip to the end of this value.
02158                  */
02159                 while ( !(ISBLANK(c))) {
02160                         CMTE_SUBGTCNOEOR(c);
02161                         /* check for separator or terminating character */
02162                         if (c == '/' || c == ',' || c == '&' || c == '$') {
02163                                 /* Reset cnt and ptr for conversion routine */
02164                                 cup->ulineptr--;
02165                                 cup->ulinecnt++;
02166                                 return(0); /* return logical value */
02167                         }
02168                 }
02169                 return(0);      /* return logical value */
02170         } /* End of type logical */
02171         /* if type character, read character data */
02172         if (type == DVTYPE_ASCII)
02173                 return (_g_charstr(css, cup, ptr, cnt, c, *lcount,
02174                         elsize, nullvlu));
02175         /* Get value for variable that is not type LOGICAL or CHARACTER */
02176         if (isdigit((int) c) || c == '+' || c == '-' || c == '.') {
02177                 if (type == DVTYPE_COMPLEX) {
02178                         errn    = FENLIVCX;
02179                         return(errn);
02180                 }
02181                 return(_g_number(type, cup, lval, elsize));
02182         }
02183         /* When we get here we are looking for a VALUE.  We are at a
02184          * nonblank character which is not a digit, +, or -, separator,
02185          * comment or delimiter.
02186          * A left parenthesis indicates complex data
02187          * An apostrophe or quote indicates hollerith data
02188          * A letter o indicates octal data
02189          * A letter z indicates hexadecimal data
02190          */
02191         if (c == '(') {
02192                 return(_g_complx(css, cup, type, lval, elsize));
02193         }
02194         else if ((c == '\'') || (c == '"')) {
02195                 return(_get_quoholl(css, cup, c, type, lval, elsize));
02196         }
02197         else if (c == 'O' || c == 'o') {
02198                 return(_gocthex(css, cup, type, lval, OCTAL, elsize, nullvlu));
02199         }
02200         else if (c == 'Z' || c == 'z') {
02201                 return(_gocthex(css, cup, type, lval, HEX, elsize, nullvlu));
02202         }
02203         else {
02204                 /* No valid value.
02205                  * Reset cup->ulineptr, because this MAY have been the first
02206                  * character of a variable name.  For example, if we have:
02207                  * integer var1(3),var2, with input: var1=2, var2 = 5
02208                  * then when we try to read the value for var1(2), we will
02209                  * see 'var2'
02210                  */
02211                 cup->ulineptr--;
02212                 cup->ulinecnt++;
02213                 *nullvlu        = 2;
02214                 return(0);      /* Return null value */
02215         }
02216 }
02217 
02218 /* _g_complx - get the value for a complex number.
02219  * On entry:
02220  *              positioned at '(' for a complex number.
02221  * Returns:     0 if OK,
02222  *              -value if EOF
02223  *              > 0 with valid error number if an error
02224  */
02225 
02226 static int
02227 _g_complx(
02228         FIOSPTR css, unit*cup, ftype_t type, long *lval, long elsize)
02229 {
02230         char    c;
02231         long    mode, stat;
02232         long    zero    = 0;
02233         long    field_width;
02234         long    *field_begin;
02235         long    *field_end;
02236         int     i, errn;
02237         int     nc;
02238         ic_func *ngcf;
02239         int     inc;
02240         int     ptrfw;
02241         bcont   *slval;
02242         /*
02243          * IN reading the complex number, assume
02244          * intervening EOR is OK
02245          */
02246         if (type != DVTYPE_COMPLEX) {
02247                 errn    = FENLIVCX;     /* not complex type */
02248                 return(errn);
02249         }
02250         /*
02251          *      Call the function from the ncf_tab90 table.
02252          */
02253 
02254         ngcf    = ncf_tab90[type];
02255         mode    = 0;
02256 
02257         switch (elsize) {
02258 #ifdef _F_REAL4
02259         case 8:
02260                 mode    = MODEHP;
02261                 break;
02262 #endif
02263         case 16:
02264                 break;
02265         case 32:
02266                 mode    = MODEDP;
02267                 break;
02268         default:
02269                 return(FEKNTSUP);       /* kind not supported */
02270         }
02271         inc     = (elsize / 2) / (sizeof(bcont));
02272         slval   = (bcont*)lval;
02273 
02274         /* loop and get both real and imaginary */
02275         for (i = 0; i < 2; i++) {
02276                 do {
02277                         SUBGTC(c);      /* skip the '(' */
02278                 } while (ISBLANK(c));   /* skip blanks */
02279                 cup->ulinecnt++;        /* backup 1 character */
02280                 cup->ulineptr--;        /* backup 1 character */
02281                 field_begin     = cup->ulineptr;
02282                 field_end       = cup->ulineptr;
02283                 field_width     = cup->ulinecnt;
02284                 nc              = 0;
02285 
02286                 while (nc < cup->ulinecnt && !(ISSEP(*field_end) ||
02287                    *field_end == ')' || *field_end == '&' ||
02288                    *field_end == '$' )) {
02289                         field_end++;
02290                         nc++;
02291                 }
02292                 /* pass field_end + 1 */
02293                 field_end++;
02294                 field_width     = nc;
02295                 /* convert both the real and imaginary parts */
02296                 errn    = ngcf(field_begin, &field_width, &field_end,
02297                         &mode, slval + (i * inc), &stat, &zero, &zero);
02298 
02299                 /* If the scan failed, the input data might be
02300                  * Hollerith or hex or octal.  Allow _s_scan_extensions
02301                  * _s_scan_extensions to rescan the input and
02302                  * recompute the field width.
02303                  */
02304                 if (errn < 0) {
02305                         errn    = _nicverr(stat);
02306                 } else
02307                         errn    = 0;
02308 
02309                 /* if (errn == EX_ILLCHAR) */
02310                 if (errn == FENICVIC) {
02311                         int     errn2;
02312                         errn2   = _s_scan_extensions(slval + (i * inc),
02313                                 type, elsize, field_begin,
02314                                 field_width, &ptrfw, mode);
02315 
02316                         cup->ulineptr += ptrfw;
02317                         cup->ulinecnt -= ptrfw;
02318                         if (errn2 <= 0)
02319                                 errn    = 0;
02320                         else
02321                                 /* errors FELDUNKI and FELDSTRL
02322                                  * are currently returned.
02323                                  */
02324                                 return(FENLIVCX);
02325                 } else {
02326                         cup->ulineptr   = field_begin + field_width;
02327                         cup->ulinecnt  -= cup->ulineptr - field_begin;
02328                         if (errn != 0)
02329                                 return(errn);
02330                 }
02331                 do {
02332                         SUBGTC(c);
02333                 } while (ISBLANK(c));
02334                 if ((c != ',') && (i == 0))
02335                         return(FENLIVCX); /* err in cmplx no. form */
02336         }
02337         if ( c != ')')
02338                 return(FENLIVCX); /* err in complex number format */
02339         return(0);
02340 }
02341 
02342 /*
02343  * _g_number - Read a number.
02344  * Returns:     0 if ok
02345  *              -value if EOF
02346  *              > 0 if error
02347  */
02348 
02349 static int
02350 _g_number(
02351         ftype_t         type,
02352         unit            *cup,
02353         long            *lval,
02354         long            elsize)
02355 {
02356         long    mode, stat;
02357         long    zero = 0;
02358         long    field_width;
02359         long    *field_begin;
02360         long    *field_end;
02361         int     ss = 0;
02362         int     errn = 0;
02363         int     nc;
02364         ic_func *ngcf;
02365         int     ptrfw;
02366         bcont   *slval;
02367 
02368         mode    = 0;
02369 
02370         switch (type) {
02371         case DVTYPE_REAL:
02372                 switch (elsize) {
02373 #ifdef _F_REAL4
02374                 case 4:
02375                         mode    = MODEHP;
02376                         break;
02377 #endif
02378                 case 8:
02379                         break;
02380                 case 16:
02381                         mode    = MODEDP;
02382                         break;
02383                 default:
02384                         return(FEKNTSUP);
02385                 }
02386                 break;
02387         case DVTYPE_INTEGER:
02388                 switch (elsize) {
02389 #ifdef _F_INT4
02390                 case 4:
02391                         mode    = MODEHP;
02392                         break;
02393 #if     defined(_F_INT2) && (defined(__mips) || defined(__sv2))
02394                 case 2:
02395                         mode    = MODEWP;
02396                         break;
02397                 case 1:
02398                         mode    = MODEBP;
02399                         break;
02400 #endif  /* _F_INT2 and (mips or sv2) */
02401 #endif  /* _F_INT4 */
02402                 case 8:
02403                         break;
02404                 default:
02405                         return(FEKNTSUP);
02406                 }
02407                 break;
02408         }
02409         /*
02410          * Call the function from the ncf_tab90 table.
02411          */
02412         ngcf            = ncf_tab90[type];
02413         cup->ulinecnt++;        /* backup 1 character */
02414         cup->ulineptr--;        /* backup 1 character */
02415         field_begin     = cup->ulineptr;
02416         field_end       = cup->ulineptr;
02417         field_width     = cup->ulinecnt;
02418         slval           = (bcont*)lval;
02419         nc              = 0;
02420         while (nc < cup->ulinecnt && !(ISSEP(*field_end) ||
02421            *field_end == '&' || *field_end == '$')) {
02422                 field_end++;
02423                 nc++;
02424         }
02425         /* pass field_end + 1 */
02426         field_end++;
02427         field_width     = nc;
02428         errn    = ngcf(field_begin, &field_width, &field_end,
02429                 &mode, slval, &stat, &zero, &zero);
02430 
02431         /* If the scan failed, the input data might be
02432          * Hollerith or hex or octal.  Allow _s_scan_extensions
02433          * _s_scan_extensions to rescan the input and
02434          * recompute the field width.
02435          */
02436         if (errn < 0) {
02437                 ss      = _nicverr(stat);
02438                 if (ss == 0)
02439                         errn    = 0;
02440         } else
02441                 errn    = 0;
02442 
02443         /* if (errn == EX_ILLCHAR) */
02444         if (ss == FENICVIC) {
02445                 int     errn2;
02446                 errn2   = _s_scan_extensions(slval,
02447                         type, elsize, field_begin,
02448                         field_width, &ptrfw, mode);
02449 
02450                 cup->ulineptr   = field_begin + field_width;
02451                 cup->ulinecnt  -= cup->ulineptr - field_begin;
02452                 if (errn2 >= 0)
02453                         errn    = 0;
02454                 else
02455                         /* errors FELDUNKI and FELDSTRL
02456                          * are currently returned.
02457                          */
02458                         errn    = FENLUNKI;
02459                         return(errn);
02460         } else {
02461                 cup->ulineptr   = field_begin + field_width;
02462                 cup->ulinecnt  -= cup->ulineptr - field_begin;
02463         }
02464         return(errn);
02465 }
02466 
02467 /* _g_charstr - read a character string
02468  *
02469  * Input: cup_ulineptr will point one past the first character of the string.
02470  *      "c" will contain the first character of the string.
02471  * Returns:     0 if ok,
02472  *              -value if EOF
02473  *              > 0 if error
02474  */
02475 
02476 static int
02477 _g_charstr(
02478         FIOSPTR         css,
02479         unit            *cup,
02480         void            *p,     /* Address of variable being read */
02481         int             cnt,    /* Number of strings we expect to read */
02482         char            c,      /* First character of string. */
02483         int             lcount, /* Repeat count */
02484         long            elsize,
02485         int             *nullvlu)
02486 {
02487         int     eos;    /* eos == -1 if end or beginning of string */
02488         int     i, ch;
02489         unsigned int    len77;
02490         char    *cp;
02491         char    enddelim;
02492         char    c1;
02493         int     repcount;
02494         char    *cpold;
02495         int     errn = 0;
02496         long    *optr;
02497         int     ocnt;
02498         void    *fchp;
02499         *nullvlu = 0;
02500         /*
02501          * Character data may be enclosed in apostrophes or quotation marks.
02502          * Each apostrophe within a character constant delimited by
02503          * apostrophes must be represented by 2 consecutive apostrophes
02504          * without an intervening blank or end of record. The same holds
02505          * true for quotation marks. Character constants may be continued
02506          * from the end of one record to the beginning of the next record.
02507          * The end of the record does not cause a blank or any other
02508          * character to become part of the constant.
02509          * Blank characters, separator characters, comment characters, and
02510          * delimiter characters may appear in character constants.
02511          *
02512          * For cf77 only (F90 does not allow undelimited character on input):
02513          * If the character constant has the following properties:
02514          * 1. It does not contain blank characters,
02515          *    separator characters, comment characters, left parenthesis
02516          *    or delimiter characters.
02517          * 2. It does not cross a record boundary,
02518          * 3. the first nonblank character is not a quotation mark or
02519          *    apostrophe,
02520          * 4. the leading characters are not numeric followed by asterisk,
02521          * 5. the leading characters are not numeric followed by R, H, or L
02522          * then the enclosing apostrophes or quotation marks are not required
02523          * and apostrophes or quotation marks within the character constant
02524          * are not to be doubled.
02525          *
02526          * Let len be the length of the list item, and let w be the length
02527          * of the character constant. If len is less than or equal to w,
02528          * the leftmost len characters of the constant are transmitted to the
02529          * variable. If len is greater than w, the constant is transmitted to
02530          * the leftmost w characters of the variable and the remaining len-w
02531          * characters of the list item are filled with blanks.
02532          *
02533          * f90 allows zero-length character and it uses one input data item
02534          * from the input record.  It does not store the value to the
02535          * the zero-sized character entity.  cf77 does not allow this feature.
02536          */
02537         eos     = 0;
02538         fchp    = p;
02539         len77   = elsize;       /* Get character length */
02540         /* f90 allows zero-length character entities */
02541         cp              = fchp;
02542         repcount        = MIN(lcount,cnt);
02543         /*
02544          * If the first character is a quote or apostrophe, we expect
02545          * that character to delimit the end of the string.
02546          */
02547         if ((c == '\'') || (c == '"')) {
02548                 enddelim        = c;
02549                 /* find characters in string */
02550                 for (i = 0; i < len77 && eos == 0; i++) {
02551                         GETSTRD();
02552                                 if (eos == 0)
02553                                         *cp++   = ch;
02554                 }
02555                 if (eos == -1)
02556                         i--;
02557                 i       = len77 - i; /* If declared len > read len */
02558                 if (i > 0)
02559                         (void) memset(cp, BLANK, i);    /* blank fill */
02560                 cp      = cp + i;
02561                 while (eos != -1) {
02562                         /*
02563                          * We didn't hit the end of the string yet.
02564                          * Search for it.
02565                          */
02566                         GETSTRD();
02567                 }
02568                 while (--repcount) {
02569                         /* We have a repeat count.
02570                          * cp will point to the next element.
02571                          * Copy len77 characters to the next element. 
02572                          */
02573                         cpold   = fchp;
02574                         (void) memcpy(cp, cpold, len77);
02575                         cp      = cp + len77;   /* Next element */
02576                 }
02577         } else {
02578                 /*
02579                  * We have a character string that's not surrounded
02580                  * by quotes (or apostrophes).  Read until we see a
02581                  * blank, separator, comment, or EOR (which looks
02582                  * like a blank to us).  Store as many of them as
02583                  * we have room for.  We cannot have a repeat count
02584                  * unless we're surrounded by quotes or apostrophes.
02585                  */
02586                 if (lcount > 1) {
02587                         errn    = FENLNOVL; /* invalid char data */
02588                         return(errn);
02589                 }
02590                 /*
02591                  * Determine if this is a value or a variable name.
02592                  * Save count and pointer in case this isn't a value.
02593                  */
02594                 ocnt    = cup->ulinecnt;
02595                 optr    = cup->ulineptr;
02596                 c1      = *optr++;
02597                 ocnt--;
02598 
02599                 while (!(ISBLANK(c1))) {
02600                         /* check for separator or terminating character */
02601                         if (c1 == ',' || c1 == '/' || c1 == '&' || c == '$')
02602                                 break;  /* Assume value */
02603                         if (c1 == '=' || c1 == '(' || c1 == '%') {
02604                                 /* Reset, this MAY be the first
02605                                  * letter of a variable name.
02606                                  */
02607                                 cup->ulineptr--;
02608                                 cup->ulinecnt++;
02609                                 *nullvlu        = 2;
02610                                 return(0); /* Null value */
02611                         }
02612                         c1      = *optr++;
02613                         ocnt--;
02614                 }
02615                 while ((ISBLANK(c1)) && ocnt-- > 0)
02616                         c1      = *optr++;
02617                 if (c1 == '=' || c1 == '(' || c1 == '%') {
02618                         /*
02619                          * Reset, this MAY be the first letter
02620                          * of a variable name.
02621                          */
02622                         cup->ulineptr--;
02623                         cup->ulinecnt++;
02624                         *nullvlu        = 2;
02625                         return(0);      /* Null value */
02626                 }
02627                 /* f90 does not allow undelimited character */
02628                 errn    = FENLUNKI; /* undelimited char */
02629                 return(errn);
02630         }
02631         return(errn);
02632 }
02633 
02634 /* _get_holl - Read a hollerith string.
02635  *
02636  * Returns:     0 if a value was found,
02637  *              -value if EOF
02638  *              > 0 if an error occurred
02639  */
02640 
02641 static int
02642 _get_holl(
02643         FIOSPTR         css,
02644         unit            *cup,
02645         char            holltype,
02646         int             count,  /* Number of characters in string */
02647         ftype_t         type,   /* Type of data item */
02648         long            *lval,
02649         long            elsize)
02650 {
02651         int     i;
02652         char    *holbufptr;
02653         char    c;
02654         int     errn = 0;
02655         int     fill;
02656         /*
02657          * Read 'count' characters from the current word, packing them
02658          * left justified into lval[0].
02659          *
02660          * Can't have hollerith input for DOUBLE, COMPLEX or CHARACTER data.
02661          * Hollerith input is supported for compatibility with
02662          * old versions of namelist.
02663          *
02664          * Because we don't allow CHARACTER data, we can make the
02665          * simplifying assumption that we start on a word boundary.
02666          * Also, we are going to assume that whatever we read in will need
02667          * to fit in one word. Repeat counts are allowed. If it becomes
02668          * necessary to allow hollerith strings of > 8 characters, some
02669          * thought will need to be given as to how to handle repeat counts.
02670          */
02671         if (type == DVTYPE_COMPLEX || type == DVTYPE_ASCII ||
02672           ((type == DVTYPE_REAL) && elsize == sizeof(_f_real16))) {
02673                 errn    = FENLUNKI;
02674                 return(errn);
02675         }
02676         if (count > elsize) {
02677                 errn    = FENLIOER;
02678                 return(errn);
02679         }
02680         fill            = BLANK;
02681         holbufptr       = (char *)lval;
02682         if (holltype == 'R' || holltype == 'r') {
02683                 /* right justified */
02684                 fill            = NULLC;
02685                 holbufptr       = holbufptr + (elsize - count);
02686         }
02687         else
02688                 if (holltype == 'L' || holltype == 'l')
02689                         fill    = NULLC;
02690         /* Last character in buffer is the EOR character,
02691          * that's why we check for cup->ulinecnt > 1
02692          */
02693         for (i = 0; i < count && (cup->ulinecnt > 1) ; i++) {
02694                 SUBGTC(c); /* comment characters are not special
02695                             * within hollerith string */
02696                 *holbufptr++    = c;
02697         }
02698         if (i == count) {
02699                 /* Do we need to fill the last word? */
02700                 if (holltype == 'R' || holltype == 'r') /* right justified? */
02701                         holbufptr       = (char *)lval;
02702                 (void) memset(holbufptr, fill, elsize - count);
02703         }
02704         else {
02705                 /*
02706                  * We hit EOR before we read enough characters _or_ we had
02707                  * too many characters.
02708                  */
02709                 errn    = FENLIOER;
02710                 return(errn);
02711         }
02712         return(errn);
02713 }
02714 
02715 /* _get_quoholl
02716  * Get a hollerith string that is surrounded by quotes or apostrophes
02717  * Legal syntax is '----'L, '----'R, or '----'H
02718  *
02719  * Returns:     0 if a value was found,
02720  *              -value if EOF
02721  *              > 0 if an error occurred
02722  */
02723 
02724 static int
02725 _get_quoholl(
02726         FIOSPTR         css,
02727         unit            *cup,
02728         char            cdelim, /* Quote or apostrophe (to end hollerith) */
02729         ftype_t         type,   /* Type of data */
02730         long            *lval,  /* Value is placed here */
02731         long            elsize) /* size */
02732 {
02733         int     numchar;        /* character counter */
02734         int     j;
02735         int     fill;           /* Fill character is either ' ' or '\0' */
02736         long    holbuf;         /* Data is stored here until we know whether
02737                                    it is right or left justified. */
02738         char    *holbufptr;     /* pointer into holbuf */
02739         char    c;              /* Character read */
02740         char    *lvalcharptr;   /* Pointer to value */
02741         int     errn = 0;
02742         /*
02743          * Can't have hollerith input for DOUBLE, COMPLEX or CHARACTER data.
02744          * Hollerith input is supported for compatibility with
02745          * old versions of namelist.
02746          *
02747          * Because we don't allow CHARACTER data, we can make the
02748          * simplifying assumption that we start on a word boundary.
02749          * Also, we are going to assume that whatever we read in will need
02750          * to fit in one word. Repeat counts are allowed. If it becomes
02751          * necessary to allow hollerith strings of > 8 characters, some
02752          * thought will need to be given as to how to handle repeat counts.
02753          */
02754         if (type == DVTYPE_COMPLEX || type == DVTYPE_ASCII ||
02755            (type == DVTYPE_REAL && elsize == sizeof(_f_real16))) {
02756                 errn    = FENLUNKI;
02757                 return(errn);
02758         }
02759         lvalcharptr     = (char *)lval;
02760         holbufptr       = (char *) &holbuf;
02761         /* Do not allow quoted strings to be continued on another record. */
02762         numchar = 0;
02763         for (;;) {
02764                 SUBGTC(c);
02765                 if (c == cdelim) {
02766                         /* Allow Comment characters within quoted string */
02767                         SUBGTC(c);
02768                         if (c != cdelim)
02769                                 break;  /* That was the end of the quoted
02770                                          * string.  Otherwise, we saw two
02771                                          * quotes in a row, which means
02772                                          * we store one.
02773                                          */
02774                 }
02775                 if (++numchar > elsize) {
02776                         errn    = FENLIOER;
02777                         return(errn);
02778                 }
02779                 *holbufptr++    = c;    /* Save the character */
02780                 /*
02781                  * Last character in input buffer is not EOR character,
02782                  * that's why we check for cup->ulinecnt <= 0
02783                  */
02784                 if (cup->ulinecnt <= 0) {
02785                         errn    = FENLIOER;
02786                         return(errn);
02787                 }
02788         } /* On exit from this loop, numchar = number of chars. stored */
02789         if (c == 'L' || c == 'l')
02790                 fill    = NULLC;
02791         else if (c == 'R' || c == 'r') {
02792                 /* Right justify and store the value just read */
02793                 holbufptr       = holbufptr - 1;        /* Last character */
02794                 lvalcharptr     = lvalcharptr + (elsize - 1);
02795                 j               = elsize - numchar;
02796                 while (numchar-- > 0)
02797                         *lvalcharptr--  = *holbufptr--;
02798 
02799                 /* Fill word with 0's if necessary */
02800                 while (j-- > 0)
02801                         *lvalcharptr--  = '\0';
02802                 return(0);
02803         }
02804         else {
02805                 /* H format */
02806                 fill    = BLANK;
02807                 if (c != 'H' && c != 'h') {
02808                         /* Reset pointers since the character does */
02809                         /* not belong to this value */
02810                         cup->ulineptr--;
02811                         cup->ulinecnt++;
02812                 }
02813         }
02814         /* Do we need to fill the last word? */
02815         (void) memset(holbufptr, fill, elsize - numchar);
02816         *lval   = holbuf;
02817         return(errn);
02818 }
02819 
02820 /* _gocthex - provides octal or hex editing for compatibility with old
02821  * versions of namelist.
02822  *      Legal formats: O'123 or O'123'. Octal number may not contain blanks,
02823  *      and this is a difference with the old version of namelist.
02824  *      Legal formats: Z'1a3 or Z'1a3'.
02825  *
02826  * On input:
02827  *      cup_ulineptr should point to the character immediately following the O
02828  * Returns:     0 if a value was found,
02829  *              -value if EOF
02830  *              >0 if an error occurred
02831  * nullvlu =    1 if a null value was found
02832  *              2 if a null value was found, and it is not followed
02833  *                by another value
02834  */
02835 
02836 static int
02837 _gocthex(
02838         FIOSPTR css,
02839         unit    *cup,
02840         ftype_t type,
02841         long    *lval,
02842         int     base,
02843         long    elsize,
02844         int     *nullvlu)
02845 {
02846         char    c;
02847         char    strbuf[2];
02848         int     errn = 0;
02849         int     octshift = OCTSHFT;
02850         int     hexshift = HEXSHFT;
02851         /* check size in bytes of incoming variable. */
02852 #if defined(_F_REAL4) && defined(_F_INT4)
02853         if (elsize <= 4) {
02854                 octshift        = OCTSHFT4;
02855                 hexshift        = HEXSHFT4;
02856         }
02857 #endif
02858         *nullvlu        = 0;
02859         if (*cup->ulineptr != '\'') {
02860                 /* Can't be a value, might be a variable name */
02861                 cup->ulineptr--;
02862                 cup->ulinecnt++;
02863                 *nullvlu        = 2;
02864                 return(0);      /* NULL value */
02865         }
02866         /* This type of format won't work for complex or double precision */
02867         if (type == DVTYPE_COMPLEX || (type == DVTYPE_REAL &&
02868             elsize == sizeof(_f_real16))) {
02869                 errn    = FENLUNKI;     /* type mismatch */
02870                 return(errn);
02871         }
02872         /* if not enough characters in record for octal/hex constant, err */
02873         if (cup->ulinecnt <= 1) {
02874                 errn    = FENLIOER;
02875                 return(errn);
02876         }
02877         SUBGTC(c);      /* Skip the apostrophe */
02878         SUBGTC(c);      /* and get the next character */
02879         *lval           = 0;
02880         strbuf[1]       = '\0';
02881         while (!(ISBLANK(c)) && c != '\'') {
02882                 if (base == OCTAL) {
02883                         if ((!isdigit((int) c)) || (c == '9') ||
02884                                 (*lval >> octshift)) {
02885                                         errn    = FENICVIC; /* NICV type err */
02886                                         return(errn);
02887                         }
02888                         *lval   = (*lval * 8) + c - '0';
02889                 }
02890                 else { /* Check for hex digit or overflow */
02891                         if ((!isxdigit(c)) || (*lval >> hexshift)) {
02892                                 errn    = FENICVIC;     /* NICV type err */
02893                                 return(errn);
02894                         }
02895                         strbuf[0]       = c;
02896                         *lval   = (*lval * 16) +
02897                                         (int) strtol(strbuf, (char **)NULL, 16);
02898                 }
02899                 /* check for comment after value */
02900                 CMTE_SUBGTC(c);
02901                 if (c == ',') {
02902                         cup->ulineptr--;
02903                         cup->ulinecnt++; /* to read separator after */
02904                         break;  /* return from this routine */
02905                 }
02906         }
02907         return(errn);   /* indicate value */
02908 }
02909 
02910 /*
02911  *      _nl_stride_dv
02912  *              Call a specified function to transfer a data area defined
02913  *              by a dopevector.  This corresponds to an array section.
02914  *      Arguments
02915  *              dv      - dope vector which describes the array section.
02916  *              sectn   - Dimension information in input record.
02917  *      Return Value
02918  *              0               normal return
02919  *              FERDPEOF        if end of file condition
02920  *              >0              if error condition
02921  */
02922 
02923 static int
02924 _nl_stride_dv(
02925         FIOSPTR         css,
02926         unit            *cup,
02927         DopeVectorType  *dv,
02928         struct DvDimen  *sectn,
02929         char            *lastch,
02930         long            strbegend[3])
02931 {
02932         int             nd;
02933         int             i;
02934         long            extent;                 /* extent of first dimension */
02935         long            inc;                    /* stride in items */
02936         long            ret = 0;
02937         ftype_t         f90type;                /* F90 data type code */
02938         long            elsize;                 /* byte size of each element */
02939         long            element_stride;         /* 1 iff elsize divides stride*/
02940         register long   id1, id2, id3, id4, id5, id6, id7;
02941         struct DvDimen  *dvdimen;
02942         long            badjust;                /* offset for collapsed dims */
02943         bcont           *addr;                  /* for numeric data */
02944         char            *baddr;                 /* for byte-oriented data */
02945         void            *addr2, *addr3, *addr4;
02946         void            *addr5, *addr6;
02947         struct DvDimen  dimen[MAXDIM];
02948         long            begt = strbegend[1];
02949         long            endt = strbegend[2];
02950 
02951         /* Assertions */
02952         assert ( dv != NULL );
02953         assert ( dv->type_lens.int_len > 0 );
02954 
02955         if (dv->p_or_a && (dv->assoc == 0))
02956                 return(FEPTRNAS);               /* pointer not associated */
02957 
02958         f90type = dv->type_lens.type;
02959         nd      = dv->n_dim;
02960         badjust = 0;
02961 
02962 /*
02963  *      Make a local copy of dimension information so we may optimize it.
02964  */
02965         for (i = 0; i < nd; i++)
02966                 dimen[i]        = dv->dimension[i];
02967 
02968 /*
02969  *      Fold any indexes into the new dimension structure.  The
02970  *      result is that we can ignore the low_bound field in the
02971  *      nested loops. 
02972  *
02973  *      We also collapse (remove) indexed dimensions and 
02974  *      unindexed dimensions with extents of one.
02975  */
02976         dvdimen = dv->dimension;
02977         for (i = 0; i < nd; i++) {
02978                 if (sectn == NULL) {
02979 
02980                         /* bail out here if any extent is 0 */
02981                         if (dvdimen[i].extent == 0)
02982                                 return(0);      
02983                 }
02984                 else {
02985                         /* collapse this indexed dimension */
02986                         badjust += (sectn[i].low_bound -
02987                                     dvdimen[i].low_bound) * 
02988                                         dvdimen[i].stride_mult;
02989                         if (dvdimen[i].extent != sectn[i].extent)
02990                                 dimen[i].extent = sectn[i].extent;
02991                         if (dvdimen[i].stride_mult != sectn[i].stride_mult)
02992                                 dimen[i].stride_mult = sectn[i].stride_mult;
02993                 }
02994         }
02995 
02996         if (f90type == DVTYPE_ASCII) {
02997 
02998                 elsize          = _fcdlen(dv->base_addr.charptr); /* in bytes */
02999                 extent          = dimen[0].extent;
03000                 inc             = 0;
03001                 element_stride  = 1;
03002 
03003                 if (extent > 1) {
03004                         register int    stm = dimen[0].stride_mult;
03005 
03006                         inc     = stm / elsize;
03007                         if (inc * elsize != stm)
03008                         element_stride  = 0;    /* it's a section of substrings */
03009                 }
03010         
03011                 baddr   = _fcdtocp(dv->base_addr.charptr) +
03012                                 badjust * (dv->type_lens.int_len >> 3);
03013                 
03014                 switch(nd) {
03015                 case 7:
03016                     for (id7 = 0; id7 < dimen[6].extent; id7++) {
03017                       addr6     = baddr;
03018                 case 6:
03019                       for (id6 = 0; id6 < dimen[5].extent; id6++) {
03020                         addr5   = baddr;
03021                 case 5:
03022                         for (id5 = 0; id5 < dimen[4].extent; id5++) {
03023                           addr4 = baddr;
03024                 case 4:
03025                           for (id4 = 0; id4 < dimen[3].extent; id4++) {
03026                             addr3       = baddr;
03027                 case 3:
03028                             for (id3 = 0; id3 < dimen[2].extent; id3++) {
03029                               addr2     = baddr;
03030                 case 2:
03031                               for (id2 = 0; id2 < dimen[1].extent; id2++) {
03032                 case 1:
03033                                 if ((element_stride == 1) && (strbegend[0] == 0)) {
03034                                   ret   = _nlread(css, f90type, cup, baddr,
03035                                              elsize, extent, inc, lastch);
03036                                   if (ret != 0) goto done;
03037                                 }
03038                                 else {
03039                                   char  *ba;
03040                                   char  *newba;
03041                                   int   newelsz;
03042                                   ba    = baddr;
03043                                   if (strbegend[0] == 0) {
03044                                     for (id1 = 0; id1 < extent; id1++) {
03045                                       ret = _nlread(css, f90type, cup, ba,
03046                                                elsize, 1, 0, lastch);
03047                                       if (ret != 0) goto done;
03048                                       ba        += dimen[0].stride_mult;
03049                                     }
03050                                   } else {
03051                                     if (begt < 1 )
03052                                       begt = 1;
03053                                     else if (begt > elsize) {
03054                                       ret       = FENLUNKN;
03055                                       goto done;
03056                                     }
03057                                     if (endt < 1 )
03058                                       endt = elsize;
03059                                     else if ((endt > elsize) || (endt < begt)) {
03060                                       ret       = FENLUNKN;
03061                                       goto done;
03062                                     }
03063                                     for (id1 = 0; id1 < extent; id1++) {
03064                                       newba     = ba + (begt - 1);
03065                                       newelsz   = (endt - begt) + 1;
03066                                       ret = _nlread(css, f90type, cup,
03067                                         newba, newelsz, 1, 0, lastch);
03068                                       if (ret != 0)
03069                                         goto done;
03070                                       ba        += dimen[0].stride_mult;
03071                                     }
03072                                   }
03073                                 }
03074         
03075                                 if (nd == 1) goto done;
03076                                 baddr   += dimen[1].stride_mult;
03077                               }
03078                               if (nd == 2) goto done;
03079                               baddr     = addr2;
03080                               baddr     += dimen[2].stride_mult;
03081                             }
03082                             if (nd == 3) goto done;
03083                             baddr       = addr3;
03084                             baddr       += dimen[3].stride_mult;
03085                           }
03086                           if (nd == 4) goto done;
03087                           baddr = addr4;
03088                           baddr += dimen[4].stride_mult;
03089                         }
03090                         if (nd == 5) goto done;
03091                         baddr   = addr5;
03092                         baddr   += dimen[5].stride_mult;
03093                       }
03094                       if (nd == 6) goto done;
03095                       baddr     = addr6;
03096                       baddr     += dimen[6].stride_mult;
03097                     }
03098                 }
03099 
03100         }
03101         else {                          /* numeric data */
03102 
03103                 int bshft;      /* 0 or 1; shift count for ratio of             */
03104                                 /* stride_mult units to basic storage unit      */
03105                                 /* size.                                        */
03106 
03107                 /*
03108                  *      We only support dopevector stride mults with units
03109                  *      scaled by sizeof(long) or sizeof(bcont).
03110                  */
03111 #if     defined(__mips) || defined(_LITTLE_ENDIAN) || defined(__sv2)
03112                 assert( SMSCALE(dv) == sizeof(bcont) ||
03113                         SMSCALE(dv) == sizeof(_f_int2) ||
03114                         SMSCALE(dv) == sizeof(_f_int4) ||
03115                         SMSCALE(dv) == sizeof(long)     );
03116 #else
03117                 assert( SMSCALE(dv) == sizeof(bcont) ||
03118                         SMSCALE(dv) == sizeof(long)     );
03119 #endif
03120 
03121                 /* the -1 is not possible but check for it */
03122                 assert( SMSHIFT(dv) != -1);
03123 
03124                 element_stride  = 1;
03125                 elsize          = dv->type_lens.int_len >> 3;
03126                 extent          = dimen[0].extent;
03127                 inc             = 0;
03128                 bshft           = SMSHIFT(dv);
03129 
03130                 if (extent > 1) {
03131                     int bytes_per_sm = dimen[0].stride_mult*(signed)SMSCALE(dv);
03132                     inc = bytes_per_sm / elsize;
03133                     if (inc * elsize != bytes_per_sm)
03134                         element_stride  = 0;    /* section across derived type */
03135                 }
03136 
03137                 addr    = (bcont*)dv->base_addr.a.ptr + (badjust << bshft);
03138                 
03139                 switch(nd) {
03140                 case 7:
03141                     for (id7 = 0; id7 < dimen[6].extent; id7++) {
03142                       addr6     = addr;
03143                 case 6:
03144                       for (id6 = 0; id6 < dimen[5].extent; id6++) {
03145                         addr5   = addr;
03146                 case 5:
03147                         for (id5 = 0; id5 < dimen[4].extent; id5++) {
03148                           addr4 = addr;
03149                 case 4:
03150                           for (id4 = 0; id4 < dimen[3].extent; id4++) {
03151                             addr3       = addr;
03152                 case 3:
03153                             for (id3 = 0; id3 < dimen[2].extent; id3++) {
03154                               addr2     = addr;
03155                 case 2:
03156                               for (id2 = 0; id2 < dimen[1].extent; id2++) {
03157                 case 1:
03158                                 if (element_stride)  {
03159                                   ret   = _nlread(css, f90type, cup, addr,
03160                                         elsize, extent, inc, lastch);
03161                                 }
03162                                 else {
03163                                   bcont *ad;
03164                                   ad    = addr;
03165                                   /* 
03166                                    * If derived type foo contains two fields,
03167                                    * real a and double precision d,  then
03168                                    * foo(1:2)%d generates this type of 
03169                                    * dopevector with a stride which is not
03170                                    * a multiple of the element size.
03171                                    */
03172                                   for (id1 = 0; id1 < extent; id1++) {
03173                                     ret = _nlread(css, f90type, cup, ad,
03174                                                elsize, 1, 0, lastch);
03175                                     if (ret != 0) goto done;
03176                                     ad  += dimen[0].stride_mult;
03177                                   }
03178                                 }
03179         
03180 
03181                                 if (ret != 0) goto done;
03182         
03183                                 if (nd == 1) goto done;
03184                                 addr    += dimen[1].stride_mult << bshft;
03185                               }
03186                               if (nd == 2) goto done;
03187                               addr      = addr2;
03188                               addr      += dimen[2].stride_mult << bshft;
03189                             }
03190                             if (nd == 3) goto done;
03191                             addr        = addr3;
03192                             addr        += dimen[3].stride_mult << bshft;
03193                           }
03194                           if (nd == 4) goto done;
03195                           addr  = addr4;
03196                           addr  += dimen[4].stride_mult << bshft;
03197                         }
03198                         if (nd == 5) goto done;
03199                         addr    = addr5;
03200                         addr    += dimen[5].stride_mult << bshft;
03201                       }
03202                       if (nd == 6) goto done;
03203                       addr      = addr6;
03204                       addr      += dimen[6].stride_mult << bshft;
03205                     }
03206                 }
03207         }
03208 
03209 done:   return(ret);
03210 }
03211 
03212 static int
03213 _nl_strd_derv(
03214         FIOSPTR         css,
03215         unit            *cup,
03216         DopeVectorType  *dv,
03217         struct DvDimen  *sectn,
03218         char            *lastch,
03219         nmlist_goli_t   *vdr,
03220         unsigned int    cnt,
03221         long            bte)
03222 {
03223         const int       bytesperchar = 1;
03224         int             nd;
03225         int             i;
03226         long            badjust;        /* offset for collapsed dims */
03227         long            elsize;         /* byte size of each element */
03228         long            ret = 0;
03229         long            sizeamt;        /* unit for stride mult */
03230         register long   id1, id2, id3, id4, id5, id6, id7;
03231         struct DvDimen  *dvdimen;
03232         struct DvDimen  dimen[MAXDIM];
03233 
03234         nd      = dv->n_dim;
03235         badjust = 0;
03236 
03237 /*      Make a local copy of dimension information to optimize it. */
03238         for (i = 0; i < nd; i++)
03239                 dimen[i]        = dv->dimension[i];
03240 
03241 /*      Fold any indexes into the new dimension structure.  The
03242  *      result is that we can ignore the low_bound field in the
03243  *      nested loops. 
03244  *
03245  *      We also collapse (remove) indexed dimensions and 
03246  *      unindexed dimensions with extents of one.
03247  */
03248         dvdimen = dv->dimension;
03249         for (i = 0; i < nd; i++) {
03250                 if (sectn == NULL) {
03251 
03252                         /* bail out here if any extent is 0 */
03253                         if (dvdimen[i].extent == 0)
03254                                 return(0);      
03255                 }
03256                 else {
03257                         /* collapse this indexed dimension */
03258                         badjust += (sectn[i].low_bound -
03259                                     dvdimen[i].low_bound) * 
03260                                         dvdimen[i].stride_mult;
03261                         if (dvdimen[i].extent != sectn[i].extent)
03262                                 dimen[i].extent = sectn[i].extent;
03263                         if (dvdimen[i].stride_mult != sectn[i].stride_mult)
03264                                 dimen[i].stride_mult = sectn[i].stride_mult;
03265                 }
03266         }
03267 
03268         elsize  = dv->base_addr.a.el_len>> 3;
03269         bte     = (badjust * elsize);
03270         if (dv->type_lens.type == DVTYPE_DERIVEDWORD) {
03271                 sizeamt = sizeof(int);
03272         } else if (dv->type_lens.type == DVTYPE_DERIVEDBYTE) {
03273                 sizeamt = 1 * bytesperchar;
03274         } else {
03275                 sizeamt = (signed)SMSCALE(dv);
03276         }
03277 
03278         switch(nd) {
03279         case 7:
03280                 for (id7 = 0; id7 < dimen[6].extent; id7++) {
03281         case 6:
03282                  for (id6 = 0; id6 < dimen[5].extent; id6++) {
03283         case 5:
03284                   for (id5 = 0; id5 < dimen[4].extent; id5++) {
03285         case 4:
03286                    for (id4 = 0; id4 < dimen[3].extent; id4++) {
03287         case 3:
03288                     for (id3 = 0; id3 < dimen[2].extent; id3++) {
03289         case 2:
03290                      for (id2 = 0; id2 < dimen[1].extent; id2++) {
03291         case 1:
03292                       for (id1 = 0; id1 < dimen[0].extent; id1++) {
03293                         ret     = _nlrdent(css, cup, vdr, cnt, lastch, bte);
03294 
03295                         if (ret != 0) goto done;
03296                         bte += dimen[0].stride_mult * sizeamt;
03297                       }
03298                       if (nd == 1) goto done;
03299                       bte += dimen[1].stride_mult * sizeamt;
03300                      }
03301                      if (nd == 2) goto done;
03302                      bte += dimen[2].stride_mult * sizeamt;
03303                     }
03304                     if (nd == 3) goto done;
03305                     bte += dimen[3].stride_mult * sizeamt;
03306                    }
03307                    if (nd == 4) goto done;
03308                    bte += dimen[4].stride_mult * sizeamt;
03309                   }
03310                   if (nd == 5) goto done;
03311                   bte += dimen[5].stride_mult * sizeamt;
03312                  }
03313                  if (nd == 6) goto done;
03314                  bte += dimen[6].stride_mult * sizeamt;
03315                 }
03316         }
03317 done:   return(ret);
03318 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines