cifgetrec.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 static char USMID[] = "@(#) libcif/cifgetrec.c  30.18   06/27/97 14:34:02";
00038 
00039 
00040 /* -------------------------------------------------------------------------
00041  * CIF record retrieval and conversion routines
00042  * Tabs are set up to be read with tab spacing = 3
00043  * --------------------------------------------------------------------------
00044  */
00045 
00046 #define CIF_VERSION 3
00047 
00048 #ifdef _ABSOFT
00049 #include "cif.h"
00050 #else
00051 #include <cif.h>
00052 #endif
00053 
00054 #include <malloc.h>
00055 #include <memory.h>
00056 #include <stdio.h>
00057 #include <stdlib.h>
00058 #include <string.h>
00059 
00060 #include "cif_int.h"
00061 
00062 /* --- function pointer array - ASCII format conversion routines --- */
00063 
00064 static int ascii_callsite __((struct Cif_callsite *));
00065 static int ascii_cifhdr __((struct Cif_cifhdr *));
00066 static int ascii_comblk __((struct Cif_comblk *));
00067 static int ascii_const __((struct Cif_const *));
00068 static int ascii_entry __((struct Cif_entry *));
00069 static int ascii_file __((struct Cif_file *));
00070 static int ascii_loop __((struct Cif_loop *));
00071 static int ascii_include __((struct Cif_include *));
00072 static int ascii_label __((struct Cif_label *));
00073 static int ascii_message __((struct Cif_message *));
00074 static int ascii_namelist __((struct Cif_namelist *));
00075 static int ascii_object __((struct Cif_object *));
00076 static int ascii_srcfile __((struct Cif_srcfile *));
00077 static int ascii_summary __((struct Cif_summary *));
00078 static int ascii_unit __((struct Cif_unit *));
00079 static int ascii_endunit __((struct Cif_endunit *));
00080 static int ascii_usage __((struct Cif_usage *));
00081 static int ascii_f90_usage __((struct Cif_usage *));
00082 static int ascii_nd_msg __((struct Cif_nd_msg *));
00083 static int ascii_edopts __((struct Cif_edopts *));
00084 static int ascii_mach_char __((struct Cif_mach_char *));
00085 static int ascii_misc_opts __((struct Cif_misc_opts *));
00086 static int ascii_opt_opts __((struct Cif_opt_opts *));
00087 static int ascii_stmt_type __((struct Cif_stmt_type *));
00088 static int ascii_transform __((struct Cif_transform *));
00089 
00090 static int ascii_cdir __((struct Cif_cdir *));
00091 static int ascii_cdir_doshared __((struct Cif_cdir_doshared *));
00092 static int ascii_geometry __((struct Cif_geometry *));
00093 static int ascii_continuation __((struct Cif_continuation *));
00094 
00095 static int ascii_c_tag __((struct Cif_c_tag *));
00096 static int ascii_c_opts __((struct Cif_c_opts *));
00097 static int ascii_c_message __((struct Cif_c_message *));
00098 static int ascii_c_const __((struct Cif_c_const *));
00099 static int ascii_c_entry __((struct Cif_c_entry *));
00100 static int ascii_c_object __((struct Cif_c_object *));
00101 static int ascii_c_entry_end __((struct Cif_c_entry_end *));
00102 static int ascii_c_lint_directive __((struct Cif_c_lint_directive *));
00103 static int ascii_c_macro_def __((struct Cif_c_macro_def *));
00104 static int ascii_c_macro_undef __((struct Cif_c_macro_undef *));
00105 static int ascii_c_macro_usage __((struct Cif_c_macro_usage *));
00106 
00107 #ifndef CRAY2
00108 static int ascii_f90_callsite __((struct Cif_f90_callsite *));
00109 static int ascii_f90_comblk __((struct Cif_f90_comblk *));
00110 static int ascii_f90_const __((struct Cif_f90_const *));
00111 static int ascii_f90_entry __((struct Cif_f90_entry *));
00112 static int ascii_f90_loop __((struct Cif_f90_loop *));
00113 static int ascii_f90_derived_type __((struct Cif_f90_derived_type *));
00114 static int ascii_f90_label __((struct Cif_f90_label *));
00115 static int ascii_f90_namelist __((struct Cif_f90_namelist *));
00116 static int ascii_f90_object __((struct Cif_f90_object *));
00117 static int ascii_f90_misc_opts __((struct Cif_f90_misc_opts *));
00118 static int ascii_f90_opt_opts __((struct Cif_f90_opt_opts *));
00119 static int ascii_f90_begin_scope __((struct Cif_f90_begin_scope *));
00120 static int ascii_f90_end_scope __((struct Cif_f90_end_scope *));
00121 static int ascii_f90_scope_info __((struct Cif_f90_scope_info *));
00122 static int ascii_f90_use_module __((struct Cif_f90_use_module *));
00123 static int ascii_f90_rename __((struct Cif_f90_rename *));
00124 static int ascii_f90_int_block __((struct Cif_f90_int_block *));
00125 static int ascii_f90_vectorization __((struct Cif_f90_vectorization *));
00126 
00127 static int ascii_BE_node __((struct Cif_BE_node *));
00128 static int ascii_BE_fid __((struct Cif_BE_fid *));
00129 static int ascii_cc_type __((struct Cif_cc_type *));
00130 static int ascii_cc_entry __((struct Cif_cc_entry *));
00131 static int ascii_cc_obj __((struct Cif_cc_obj *));
00132 static int ascii_cc_subtype __((struct Cif_cc_subtype *));
00133 static int ascii_cc_enum __((struct Cif_cc_enum *));
00134 static int ascii_cc_expr __((struct Cif_cc_expr *));
00135 static int ascii_src_pos __((struct Cif_src_pos *));
00136 static int ascii_orig_cmd __((struct Cif_orig_cmd *));
00137 #endif
00138 
00139 static int (*ascii_record[CIF_MAXRECORD]) () = {
00140         0,                                                                      /* 00= */
00141         ascii_callsite,                         /* 01= CIF_CALLSITE */
00142         ascii_cifhdr,                           /* 02= CIF_CIFHDR */
00143         ascii_comblk,                           /* 03= CIF_COMBLK */
00144         ascii_const,                            /* 04= CIF_CONST */
00145         ascii_cdir,                             /* 05= CIF_CDIR */
00146         ascii_entry,                            /* 06= CIF_ENTRY */
00147         ascii_file,                             /* 07= CIF_FILE */
00148         ascii_loop,                             /* 08= CIF_LOOP */
00149         ascii_include,                          /* 09= CIF_INCLUDE */
00150         ascii_label,                            /* 10= CIF_LABEL */
00151         ascii_message,                          /* 11= CIF_MESSAGE */
00152         ascii_namelist,                         /* 12= CIF_NAMELIST */
00153         ascii_object,                           /* 13= CIF_OBJECT */
00154         ascii_srcfile,                          /* 14= CIF_SRCFILE */
00155         ascii_summary,                          /* 15= CIF_SUMMARY */
00156         ascii_cdir_doshared,                    /* 16= CIF_CDIR_DOSHARED*/
00157         ascii_unit,                             /* 17= CIF_UNIT */
00158         ascii_endunit,                          /* 18= CIF_ENDUNIT */
00159         ascii_usage,                            /* 19= CIF_USAGE */
00160         ascii_nd_msg,                           /* 20= CIF_ND_MSG */
00161         ascii_edopts,                           /* 21= CIF_EDOPTS */
00162         ascii_mach_char,                        /* 22= CIF_MACH_CHAR */
00163         ascii_misc_opts,                        /* 23= CIF_MISC_OPTS */
00164         ascii_opt_opts,                         /* 24= CIF_OPT_OPTS */
00165         ascii_stmt_type,                        /* 25= CIF_STMT_TYPE */
00166         ascii_geometry,                         /* 26= CIF_GEOMETRY */
00167         ascii_continuation,                     /* 27= CIF_CONTINUATION */
00168 #ifndef CRAY2
00169         ascii_f90_callsite,                     /* 28= CIF_F90_CALLSITE */
00170         ascii_f90_comblk,                       /* 29= CIF_F90_COMBLK */
00171         ascii_f90_const,                        /* 30= CIF_F90_CONST */
00172         ascii_f90_entry,                        /* 31= CIF_F90_ENTRY */
00173         ascii_f90_loop,                         /* 32= CIF_F90_LOOP */
00174         ascii_f90_derived_type,                 /* 33= CIF_F90_DERIVED_TYPE */
00175         ascii_f90_label,                        /* 34= CIF_F90_LABEL */
00176         ascii_f90_namelist,                     /* 35= CIF_F90_NAMELIST */
00177         ascii_f90_object,                       /* 36= CIF_F90_OBJECT */
00178         ascii_f90_misc_opts,                    /* 37= CIF_F90_MISC_OPTS */
00179         ascii_f90_opt_opts,                     /* 38= CIF_F90_OPT_OPTS */
00180         ascii_f90_begin_scope,                  /* 39= CIF_F90_BEGIN_SCOPE */
00181         ascii_f90_end_scope,                    /* 40= CIF_F90_END_SCOPE */
00182         ascii_f90_scope_info,                   /* 41= CIF_F90_SCOPE_INFO */
00183         ascii_f90_use_module,                   /* 42= CIF_F90_USE_MODULE */
00184         ascii_f90_rename,                       /* 43= CIF_F90_RENAME */
00185         ascii_f90_int_block,                    /* 44= CIF_F90_INT_BLOCK */
00186         ascii_f90_vectorization,                /* 45= CIF_F90_VECTORIZATION */
00187         ascii_BE_node,                          /* 46= CIF_BE_NODE */
00188 #else
00189         NULL, NULL, NULL, NULL,
00190         NULL, NULL, NULL, NULL,
00191         NULL, NULL, NULL, NULL,
00192         NULL, NULL, NULL, NULL,
00193         NULL, NULL, NULL,
00194 #endif /* ndef CRAY2 */
00195         ascii_transform,                        /* 47= CIF_TRANSFORM */
00196         0,0,                                    /* 48-49 */
00197         ascii_BE_fid,                           /* 50= CIF_BE_FID */
00198         ascii_c_tag,                            /* 51= CIF_C_TAG */
00199         ascii_c_opts,                           /* 52= CIF_C_OPTS */
00200         ascii_c_message,                        /* 53= CIF_C_MESSAGE */
00201         ascii_c_const,                          /* 54= CIF_C_CONST */
00202         ascii_c_entry,                          /* 55= CIF_C_ENTRY */
00203         ascii_c_object,                         /* 56= CIF_C_OBJECT */
00204         ascii_c_lint_directive,                 /* 57= CIF_C_LINT_DIRECTIVE */
00205         ascii_c_macro_def,                      /* 58= CIF_C_MACRO_DEF */
00206         ascii_c_macro_undef,                    /* 59= CIF_C_MACRO_UNDEF */
00207         ascii_c_macro_usage,                    /* 60= CIF_C_MACRO_USAGE */
00208         ascii_c_entry_end,                      /* 61= CIF_C_ENTRY_END */
00209         0,0,0,0,0,0,0,0,                        /* 62-69 */
00210         ascii_orig_cmd,                         /* 70= CIF_ORIG_CMD */
00211         0,0,0,0,0,0,0,0,0,                      /* 71-79 */
00212         ascii_cc_type,                          /* 80 = CIF_CC_TYPE */
00213         ascii_cc_entry,                         /* 81 = CIF_CC_ENTRY */
00214         ascii_cc_obj,                           /* 82 = CIF_CC_OBJ */
00215         ascii_cc_subtype,                       /* 83 = CIF_CC_SUBTYPE */
00216         ascii_cc_enum,                          /* 84 = CIF_CC_ENUM */
00217         ascii_cc_expr,                          /* 85 = CIF_CC_EXPR */
00218         ascii_src_pos                           /* 86 = CIF_SRC_POS */
00219 
00220 
00221 };
00222 
00223 
00224 
00225 /* --- valid binary record indicators --- */
00226 static short valid_record[CIF_MAXRECORD] = {
00227         NO,             /* 00= */
00228         YES,            /* 01= CIF_CALLSITE */
00229         YES,            /* 02= CIF_CIFHDR */
00230         YES,            /* 03= CIF_COMBLK */
00231         YES,            /* 04= CIF_CONST */
00232         YES,            /* 05= CIF_CDIR */
00233         YES,            /* 06= CIF_ENTRY */
00234         YES,            /* 07= CIF_FILE */
00235         YES,            /* 08= CIF_LOOP */
00236         YES,            /* 09= CIF_INCLUDE */
00237         YES,            /* 10= CIF_LABEL */
00238         YES,            /* 11= CIF_MESSAGE */
00239         YES,            /* 12= CIF_NAMELIST */
00240         YES,            /* 13= CIF_OBJECT */
00241         YES,            /* 14= CIF_SRCFILE */
00242         YES,            /* 15= CIF_SUMMARY */
00243         YES,            /* 16= CIF_CDIR_DOSHARED */
00244         YES,            /* 17= CIF_UNIT */
00245         YES,            /* 18= CIF_ENDUNIT */
00246         YES,            /* 19= CIF_USAGE */
00247         YES,            /* 20= CIF_ND_MSG */
00248         YES,            /* 21= CIF_EDOPTS */
00249         YES,            /* 22= CIF_MACH_CHAR */
00250         YES,            /* 23= CIF_MISC_OPTS */
00251         YES,            /* 24= CIF_OPT_OPTS */
00252         YES,            /* 25= CIF_STMT_TYPE */
00253         YES,            /* 26= CIF_GEOMETRY */
00254         YES,            /* 27= CIF_CONTINUATION */
00255         YES,            /* 28= CIF_F90_CALLSITE */
00256         YES,            /* 29= CIF_F90_COMBLK */
00257         YES,            /* 30= CIF_F90_CONST */
00258         YES,            /* 31= CIF_F90_ENTRY */
00259         YES,            /* 32= CIF_F90_LOOP */
00260         YES,            /* 33= CIF_F90_DERIVED_TYPE */
00261         YES,            /* 34= CIF_F90_LABEL */
00262         YES,            /* 35= CIF_F90_NAMELIST */
00263         YES,            /* 36= CIF_F90_OBJECT */
00264         YES,            /* 37= CIF_F90_MISC_OPTS */
00265         YES,            /* 38= CIF_F90_OPT_OPTS */
00266         YES,            /* 39= CIF_F90_BEGIN_SCOPE */
00267         YES,            /* 40= CIF_F90_END_SCOPE */
00268         YES,            /* 41= CIF_F90_SCOPE_INFO */
00269         YES,            /* 42= CIF_F90_USE_MODULE */
00270         YES,            /* 43= CIF_F90_RENAME */
00271         YES,            /* 44= CIF_F90_INT_BLOCK */
00272         YES,            /* 45= CIF_F90_VECTORIZATION */
00273         YES,            /* 46= CIF_BE_NODE */
00274         YES,            /* 47 = CIF_TRANSFORM */
00275         YES,            /* 48 = CIF_FILEDIR */
00276         YES,            /* 49 = CIF_UNITDIR */
00277         YES,            /* 50 = CIF_BE_FID */
00278         YES,            /* 51= CIF_C_TAG */
00279         YES,            /* 52= CIF_C_OPTS */
00280         YES,            /* 53= CIF_C_MESSAGE */
00281         YES,            /* 54= CIF_C_CONST */
00282         YES,            /* 55= CIF_C_ENTRY */
00283         YES,            /* 56= CIF_C_OBJECT */
00284         YES,            /* 57= CIF_C_LINT_DIRECTIVE */
00285         YES,            /* 58= CIF_C_MACRO_DEF */
00286         YES,            /* 59= CIF_C_MACRO_UNDEF */
00287         YES,            /* 60= CIF_C_MACRO_USAGE */
00288         YES,            /* 61= CIF_C_ENTRY_END */
00289         NO, NO, NO, NO, NO, NO, NO, NO, /* 62-69 */
00290         YES,            /* 70= CIF_ORIG_CMD */
00291         NO, NO, NO, NO, NO, NO, NO, NO, NO, /* 71-79 */
00292         YES,            /* 80= CIF_CC_TYPE */
00293         YES,            /* 81= CIF_CC_ENTRY */
00294         YES,            /* 82= CIF_CC_OBJ */
00295         YES,            /* 83= CIF_CC_SUBTYPE */
00296         YES,            /* 84= CIF_CC_ENUM */
00297         YES,            /* 85= CIF_CC_EXPR */
00298         YES             /* 86= CIF_SRC_POS */
00299 
00300 };
00301 
00302 /* Buffer to use when mapping a version 1 cif to a version 2 cif record.
00303  * Required because some records increased in size so reading a v2 record
00304  * into space for a v1 cif would not work. Data is read into this buffer and
00305  * shaped into the correct cif record structure that the application requested.
00306  */
00307 struct Cif_generic *_cif_map_buffer = (struct Cif_generic *) NULL;
00308 
00309 
00310 static int lcifd;                                       /* cif descriptor for current invocation */
00311 static int lmode;                                       /* memory mgmt mode for current invocation */
00312 
00313 static int binary_record __((struct Cif_generic **, FILE *));
00314 
00315 /*
00316  * We need this so that when returning a v1 cif, we do not
00317  * return the file record associated with the message catalog;
00318  * when we hit the file that matches this, it will not be returned.
00319  */
00320 
00321 static int global_msgfid = -1;
00322 
00323 /* --------------------------------------------------------------------------
00324  * ASCII record token scanning stuff 
00325  *
00326  * The "token" routine returns a pointer to the next SEPARATOR or "\n"
00327  * delimited token in the current record.  "delim" is set to the character
00328  * that terminated the token.  The routine is initialized to begin a new
00329  * record by setting "ntoken" to the record buffer address.
00330  * --------------------------------------------------------------------------
00331  */
00332 
00333 static char *ntoken;                            /* pointer to next token in buffer */
00334 static char delim;                              /* character that terminated current token */
00335 static char *token () {
00336         char *tok;
00337 
00338         if (*ntoken == '\0')
00339                 return ((char *)NULL);
00340         else {
00341                 tok = ntoken;
00342                 delim = *ntoken++;
00343                 while (delim != SEPARATOR && delim != '\n' && delim != '\0')
00344                         delim = *ntoken++;
00345                 *(ntoken-1) = '\0';
00346                 return (tok);
00347         }
00348 }
00349 
00350 
00351 /* --------------------------------------------------------------------------
00352  * "compuse" compares two usage records by file, line, and charpos.  It is
00353  * passed to "qsort" to sort usage records.
00354  * --------------------------------------------------------------------------
00355  */
00356 
00357 static int compuse (u1, u2)
00358 struct Cif_use *u1, *u2;
00359 {
00360         int ret;
00361 
00362         if ((ret = ( u1->fid - u2->fid )) != 0)
00363                 return (ret);
00364         else if ((ret = ( u1->line - u2->line )) != 0)
00365                 return (ret);
00366         else
00367                 return ( u1->cpos - u2->cpos );
00368 }
00369 
00370 /* --------------------------------------------------------------------------
00371  *
00372  * Cif_Getrecord returns the next record from a CIF file.  If the file is an
00373  * ASCII format file, the next record from the file is read and converted
00374  * into structure format.  If a binary format file, the next record is read
00375  * from the file.  In both cases, the neccessary space to contain the
00376  * structure and associated information is acquired.  The status value is
00377  * returned via the function return value.  The pointer to the structure is
00378  * returned by setting the "cif_record" argument to the structure pointer.
00379  *
00380  * --------------------------------------------------------------------------
00381  */
00382 
00383 int Cif_Getrecord
00384 #ifdef __STDC__
00385 (int cifd, struct Cif_generic **cif_record)
00386 #else
00387 (cifd, cif_record)
00388 int cifd;                                                                       /* input CIF file descriptor */
00389 struct Cif_generic **cif_record;                /* pointer to pointer to CIF structure */
00390 #endif
00391 {
00392 
00393         int rtype;                                              /* record type code */
00394         int status = 0;                         /* status value */
00395 
00396         if (cifd < 0 || cifd >= CIF_FT_SIZE || _Cif_filetbl[cifd].form == NOT_A_CIF)
00397                 return (CIF_NOTOPEN);
00398         else if (_Cif_filetbl[cifd].optype == 'w')
00399                 return (CIF_BADREQ);
00400         lcifd = cifd;
00401 
00402         /*
00403          * If memory management mode isn't set, then set to FIXED.  If the mode is
00404          * FIXED, reset the amount of buffer used.
00405          */
00406 
00407         lmode = _Cif_filetbl[cifd].mode;
00408         if (lmode == CIF_MEM_DEFAULT) {
00409                 if ((status = Cif_Memmode (cifd, CIF_MEM_FIXED)) != 0)
00410                         return (status);
00411                 lmode = _Cif_filetbl[cifd].mode;
00412         }
00413         if (lmode == CIF_MEM_FIXED)
00414                 _Cif_memarea[_Cif_filetbl[cifd].fme].mused = 0;
00415 
00416         if (_Cif_filetbl[cifd].form == ASCII_CIF) {
00417 
00418                 /* Read next record from file.  Continue reading records until a
00419                  * record that should be returned is encountered.  The record must
00420                  * legal for this CIF version and must be allowed by the record
00421                  * mask for this file.
00422                  */
00423 
00424           do {
00425                 do {
00426                         if (_Cif_filetbl[cifd].ifull == NO) {
00427                                 if (fgets(_Cif_filetbl[cifd].ip, CIF_BUFSIZE, _Cif_filetbl[cifd].fd)
00428                                         == NULL)
00429                                 {
00430                                         if (feof (_Cif_filetbl[cifd].fd))
00431                                                 return (CIF_EOF);
00432                                         else
00433                                                 return (CIF_SYSERR);
00434                                 }
00435                         }
00436                         _Cif_filetbl[cifd].ifull = NO;
00437                         ntoken = _Cif_filetbl[cifd].ip;
00438                         rtype = atoi (token ());
00439                 } while (rtype >= CIF_MAXRECORD || ascii_record[rtype] == 0 ||
00440                          _Cif_filetbl[cifd].rmask[rtype] == '\0');
00441 
00442                 /* Allocate space for record structure and call conversion
00443                  * routine based on record type.
00444                  */
00445 
00446                 *cif_record = (struct Cif_generic *) _Cif_space[lmode]
00447                           (_Cif_structsize[rtype][_Cif_filetbl[cifd].return_version], lcifd);
00448                 if (*cif_record  == NULL)
00449                         status = CIF_NOMEM;
00450                 else {
00451                         (void) memset ((char *)*cif_record,
00452                                        '\0',
00453                                        _Cif_structsize
00454                                                 [rtype][_Cif_filetbl[cifd].return_version]);
00455 
00456                         (*cif_record)->rectype = rtype;
00457                         status = ascii_record[rtype] (*cif_record);
00458 
00459                 }
00460                 /*
00461                  * If status == maxrecord, we don't want to return this record.
00462                  * This can only happen if we are returning a v1 cif, but reading a v2
00463                  * and it is a stmt record (#25) with type CDIR; v1 didn't have that
00464                  * record
00465                  */
00466                 if (status == CIF_MAXRECORD &&
00467                     lmode == CIF_MEM_INDIV)
00468                   Cif_Free(*cif_record);
00469 
00470               } while (status == CIF_MAXRECORD);
00471         }
00472 
00473         else            /* form is BINARY_CIF so */
00474                 status = binary_record (cif_record, _Cif_filetbl[cifd].fd);
00475 
00476         return (status);
00477 }
00478 
00479 
00480 
00481 
00482 /* --------------------------------------------------------------------------
00483  * Binary record version mapping
00484  *
00485  * Converts a binary record from one version to another
00486  * --------------------------------------------------------------------------
00487  */
00488 int _Cif_binary_map_version (rtype, map_buffer, cr)
00489 int rtype;
00490 struct Cif_generic *map_buffer;
00491 struct Cif_generic *cr;
00492 {
00493 
00494   switch (rtype) {
00495 
00496   case CIF_OBJECT : {
00497     struct Cif_object *to = (struct Cif_object *) cr;
00498     struct Cif_object *from = (struct Cif_object *) map_buffer;
00499 
00500     /*
00501      * copy the required bytes to fill the return version; if there are not
00502      * enough bytes to copy, that's okay (ie if v1 copied to v2), the buffer
00503      * has sufficient space after it to avoid memory problems. If copying a
00504      * smaller version (v1) into a larger, that's also okay as we will set
00505      * the new geometry and distribution fields added in v2, below.
00506      */
00507 
00508     (void) memcpy((char *) cr, (char *) map_buffer,
00509            _Cif_shortsize[rtype][_Cif_filetbl[lcifd].return_version]);
00510 
00511     if (_Cif_filetbl[lcifd].return_version == 1) {
00512       if (from->storage == CIF_ST_DATA)  /* in v2, static was split into bss and data,
00513                                           * but as bss has the same value as static (6),
00514                                           * that's okay, so we just have to map back the
00515                                           * data variant (8)
00516                                           */
00517         to->storage = CIF_ST_STATIC;
00518     }
00519     else
00520         if (_Cif_filetbl[lcifd].version == 1) {
00521           /* returning v2, add the extra distribution and geomid */
00522           to->geomid = 0;
00523           to->dist = 0;
00524           to->pointer = 0;
00525         }
00526 
00527     break;
00528   }
00529 
00530   case CIF_CONST : {
00531     struct Cif_const *to = (struct Cif_const *) cr;
00532 
00533     /*
00534      * copy the required bytes to fill the return version; if there are not
00535      * enough bytes to copy, that's okay (ie if v1 copied to v2), the buffer
00536      * has sufficient space after it to avoid memory problems. If copying a
00537      * smaller version (v1) into a larger, that's also okay as we will set
00538      * the original form fields added in v2 below.
00539      */
00540 
00541     (void) memcpy((char *) cr, (char *) map_buffer,
00542            _Cif_shortsize[rtype][_Cif_filetbl[lcifd].return_version]);
00543 
00544     if (_Cif_filetbl[lcifd].version == 1 &&
00545         _Cif_filetbl[lcifd].return_version != 1) {
00546       /* returning v2, add the extra
00547        * original format fields
00548        */
00549 
00550       to->origform = 0;
00551       to->olen = 0;
00552       to->oform = (char *) NULL;
00553     }
00554 
00555     break;
00556   }
00557 
00558 
00559   case CIF_FILE : {
00560     struct Cif_file *to = (struct Cif_file *) cr;
00561 
00562     struct Cif_file *from = (struct Cif_file *) map_buffer;
00563 
00564     (void) memcpy((char *) cr, (char *) map_buffer,
00565            _Cif_shortsize[rtype][_Cif_filetbl[lcifd].version]);
00566            /* do NOT change this shortsize to "return_version"
00567               because we need to pick up the onlen field */
00568 
00569     break;
00570   }
00571 
00572   case CIF_COMBLK : {
00573     struct Cif_comblk *to = (struct Cif_comblk *) cr;
00574 
00575     /*
00576      * copy the required bytes to fill the return version; if there are not
00577      * enough bytes to copy, that's okay (ie if v1 copied to v2), the buffer
00578      * has sufficient space after it to avoid memory problems. If copying a
00579      * smaller veriosn (v1) into a larger, that's also okay as we will set
00580      * the new distribution field added in v2, below.
00581      */
00582 
00583     (void) memcpy((char *) cr, (char *) map_buffer,
00584            _Cif_shortsize[rtype][_Cif_filetbl[lcifd].return_version]);
00585 
00586     if (_Cif_filetbl[lcifd].version == 1 &&
00587         _Cif_filetbl[lcifd].return_version != 1)  /* add the extra geomid */
00588       to->dist = 0;
00589 
00590     break;
00591   }
00592 
00593   case CIF_USAGE : {
00594     struct Cif_usage *to = (struct Cif_usage *) cr;
00595 
00596     /*
00597      * copy the required bytes to fill the return version; if there are not
00598      * enough bytes to copy, that's okay (ie if v1 copied to v2), the buffer
00599      * has sufficient space after it to avoid memory problems. If copying a
00600      * smaller version (v1) into a larger, that's also okay as we will set
00601      * the new nmembs and membs fields added in v2, below.
00602      */
00603 
00604     (void) memcpy((char *) cr, (char *) map_buffer,
00605            _Cif_shortsize[rtype][_Cif_filetbl[lcifd].return_version]);
00606 
00607     if (_Cif_filetbl[lcifd].version == 1 &&
00608         _Cif_filetbl[lcifd].return_version != 1) {
00609         to->nmembs = 0;
00610         to->membs = (long *) NULL;
00611     }
00612 
00613     break;
00614   }
00615 
00616   case CIF_MACH_CHAR : {
00617     struct Cif_mach_char *to = (struct Cif_mach_char *) cr;
00618 
00619     /*
00620      * copy the required bytes to fill the return version; if there are not
00621      * enough bytes to copy, that's okay (ie if v1 copied to v2), the buffer
00622      * has sufficient space after it to avoid memory problems. If copying a
00623      * smaller veriosn (v1) into a larger, that's also okay as we will set
00624      * the new distribution field added in v2, below.
00625      */
00626 
00627     (void) memcpy((char *) cr, (char *) map_buffer,
00628            _Cif_shortsize[rtype][_Cif_filetbl[lcifd].return_version]);
00629 
00630     if (_Cif_filetbl[lcifd].version == 1 &&
00631         _Cif_filetbl[lcifd].return_version != 1) { /* add the extra fields */
00632         to->numbanks = 0;       /* number of memory banks */
00633         to->numcpus = 0;        /* number of cpus */
00634         to->instbufsize = 0;    /* instruction buffer size */
00635         to->clockperiod = 0;    /* clock period in picoseconds */
00636         to->numclregs = 0;      /* number of register clusters */
00637         to->bankbusytime = 0;   /* number of clock periods that the memory bank is reserved */
00638     }
00639 
00640     break;
00641   }
00642 
00643   case CIF_C_MESSAGE : {
00644     struct Cif_c_message *to = (struct Cif_c_message *) cr;
00645 
00646     (void) memcpy((char *) cr, (char *) map_buffer,
00647            _Cif_shortsize[rtype][_Cif_filetbl[lcifd].return_version]);
00648 
00649     if (_Cif_filetbl[lcifd].version == 1 &&
00650         _Cif_filetbl[lcifd].return_version != 1)
00651         /* add in extra msgcode field */
00652         to->msgcode = 0;
00653 
00654     break;
00655   }
00656 
00657   case CIF_MISC_OPTS : {
00658     struct Cif_misc_opts *to = (struct Cif_misc_opts *) cr;
00659 
00660     (void) memcpy((char *) cr, (char *) map_buffer,
00661            _Cif_shortsize[rtype][_Cif_filetbl[lcifd].return_version]);
00662 
00663     if (_Cif_filetbl[lcifd].version == 1 &&
00664         _Cif_filetbl[lcifd].return_version != 1)  { /* add in extra v2 fields */
00665       to->llen = 0;
00666       to->cifopt = 0;
00667       to->inputlen = 0;
00668       to->runtime = 0;
00669       to->numincs = 0;
00670     }
00671 
00672     break;
00673   }
00674 
00675 
00676   case CIF_OPT_OPTS : {
00677 
00678     if (_Cif_filetbl[lcifd].return_version == 1) { /* map a v2 cif to pass to a v1 application */
00679 
00680       struct Cif_opt_opts *from = (struct Cif_opt_opts *) map_buffer;
00681       struct Cif_opt_opts_1 *to = (struct Cif_opt_opts_1 *) cr;
00682 
00683       to->values = from->values;
00684 
00685     } else if (_Cif_filetbl[lcifd].version == 1) {
00686           /* a v1 cif to a v(>1) application */
00687 
00688           struct Cif_opt_opts_1 *from = (struct Cif_opt_opts_1 *) map_buffer;
00689           struct Cif_opt_opts *to = (struct Cif_opt_opts *) cr;
00690 
00691           to->values = from->values;
00692           to->inlevel = 0;  /* v1 cif didn't set this inline level field */
00693 
00694     } else {
00695           /* map v2 to v3 or vice versa */
00696           (void) memcpy((char *) cr, (char *) map_buffer,
00697              _Cif_shortsize[rtype][_Cif_filetbl[lcifd].return_version]);
00698     }
00699     break;
00700   }
00701 
00702 
00703   case CIF_C_ENTRY : {
00704 
00705     if (_Cif_filetbl[lcifd].return_version == 1) { /* map a v2 cif to pass to a v1 application */
00706 
00707       struct Cif_c_entry *from = (struct Cif_c_entry *) map_buffer;
00708       struct Cif_c_entry_1 *to = (struct Cif_c_entry_1 *) cr;
00709 
00710       to->rectype = from->rectype;
00711       to->ptype = from->ptype;
00712       if (from->symclass == 5)
00713         to->symclass = 0;
00714       else
00715         to->symclass = from->symclass;
00716       to->retvalue = from->retvalue;
00717       to->varargs = from->varargs;
00718       to->scope = from->scope;
00719       to->nlen = from->nlen;
00720       to->symid = from->symid;
00721       to->nargs = from->nargs;
00722       to->nmods = from->nmods;
00723       to->qual = from->qual;
00724       to->btype = from->btype;
00725 
00726     }
00727     else
00728 
00729       if (_Cif_filetbl[lcifd].version == 1) {
00730         /* a v1 cif to a v(>1) application */
00731         struct Cif_c_entry_1 *from = (struct Cif_c_entry_1 *) map_buffer;
00732         struct Cif_c_entry *to = (struct Cif_c_entry *) cr;
00733 
00734         to->rectype = from->rectype;
00735         to->ptype = from->ptype;
00736         to->symclass = from->symclass;
00737         to->retvalue = from->retvalue;
00738         to->varargs = from->varargs;
00739         to->tagid = 0;
00740         to->scope = from->scope;
00741         to->nlen = from->nlen;
00742         to->symid = from->symid;
00743         to->nargs = from->nargs;
00744         to->nmods = from->nmods;
00745         to->qual = from->qual;
00746         to->btype = from->btype;
00747         to->link = 0;
00748 
00749       }
00750       else {
00751         (void) memcpy((char *) cr, (char *) map_buffer,
00752                       _Cif_shortsize[rtype][_Cif_filetbl[lcifd].return_version]);
00753     }
00754 
00755     break;
00756   }
00757 
00758   case CIF_C_TAG : {
00759     struct Cif_c_tag *tag = (struct Cif_c_tag *) cr;
00760 
00761     (void) memcpy((char *) cr, (char *) map_buffer,
00762            _Cif_shortsize[rtype][_Cif_filetbl[lcifd].return_version]);
00763 
00764     /* v1 entity value 10 maps to v2 enity values of 9 */
00765 
00766     if (_Cif_filetbl[lcifd].version == 1 &&
00767         _Cif_filetbl[lcifd].return_version != 1 &&
00768         tag->entity == 10)
00769       tag->entity = 9;
00770     else
00771       if (_Cif_filetbl[lcifd].version != 1 &&
00772           _Cif_filetbl[lcifd].return_version == 1 &&
00773           tag->entity == 9)
00774         tag->entity = 10;
00775     
00776     break;
00777   }
00778 
00779   case CIF_C_OBJECT : {
00780 
00781       struct Cif_c_object *obj = (struct Cif_c_object *) cr;
00782 
00783       (void) memcpy((char *) cr, (char *) map_buffer,
00784                     _Cif_shortsize[rtype][_Cif_filetbl[lcifd].return_version]);
00785 
00786       if (_Cif_filetbl[lcifd].return_version == 1) { /* map a v2 cif to pass to a v1 application */
00787 
00788           struct Cif_c_object *from = (struct Cif_c_object *) map_buffer;
00789           struct Cif_c_object_1 *to = (struct Cif_c_object_1 *) cr;
00790 
00791           to->mods = from->mods;
00792           to->name = from->name;
00793 
00794       }
00795       else
00796 
00797           if (_Cif_filetbl[lcifd].version == 1) {
00798             /* a v1 cif to a v(>1) application */
00799 
00800             struct Cif_c_object_1 *from = (struct Cif_c_object_1 *) map_buffer;
00801             struct Cif_c_object *to = (struct Cif_c_object *) cr;
00802 
00803             to->mods = from->mods;
00804             to->name = from->name;
00805 
00806           }
00807 
00808       if (_Cif_filetbl[lcifd].version == 1 &&
00809           _Cif_filetbl[lcifd].return_version != 1 &&
00810           (obj->entity == 11 || obj->entity == 12))
00811           obj->entity --;
00812       else
00813           if (_Cif_filetbl[lcifd].version != 1 &&
00814               _Cif_filetbl[lcifd].return_version == 1 &&
00815               (obj->entity == 10 || obj->entity == 11))
00816               obj->entity ++;
00817     
00818       break;
00819   }
00820 
00821   case CIF_MESSAGE :
00822       {
00823         (void) memcpy((char *) cr, (char *) map_buffer,
00824                       _Cif_shortsize[rtype][_Cif_filetbl[lcifd].return_version]);
00825 
00826         if (_Cif_filetbl[lcifd].return_version < 3 &&
00827             _Cif_filetbl[lcifd].version == 3) {
00828 
00829           struct Cif_message *from = (struct Cif_message *) map_buffer;
00830           struct Cif_message_1 *to = (struct Cif_message_1 *) cr;
00831 
00832           to->fid = from->pfid;
00833 
00834           ((struct Cif_message *)cr)->nlen = from->nlen;
00835                 /* this kludge allows _Cif_binread() to read in the "name"
00836                    field */
00837 
00838         }
00839 
00840         break;
00841       }
00842 
00843 
00844   case CIF_F90_INT_BLOCK :
00845   case CIF_F90_DERIVED_TYPE :
00846   case CIF_BE_NODE :
00847       {
00848 
00849       (void) memcpy((char *) cr, (char *) map_buffer,
00850                     _Cif_shortsize[rtype][_Cif_filetbl[lcifd].return_version]);
00851       break;
00852     }
00853 
00854   default:
00855         /*
00856          * if we are not going to return this record, make sure that what we
00857          * are copying matches what we read (eg there is not version 1 macro
00858          * def record, but we could open a v2 cif and read with a v1 application
00859          * which should never see the macro def, but it has to be read from the
00860          * file before the next one can be
00861          */
00862 
00863         if (_Cif_filetbl[lcifd].rmask[rtype] == '\0') {
00864 
00865             (void) memcpy((char *) cr, (char *) map_buffer,
00866                    _Cif_shortsize[rtype][_Cif_filetbl[lcifd].version]);
00867 
00868           }
00869           else {
00870 
00871             (void) memcpy((char *) cr, (char *) map_buffer,
00872                    _Cif_shortsize[rtype][_Cif_filetbl[lcifd].return_version]);
00873 
00874           }
00875 
00876         /*
00877          * If we are returning a version 1 cif from a v2 cif on disk
00878          * and this is a stm_type and it is of type CDIR (80) then don't
00879          * return it as v1 cifs don't know about thie stmt type
00880          */
00881         if (rtype == CIF_STMT_TYPE &&
00882             CIFSTMT(cr)->type == CIF_TP_CDIR &&
00883             _Cif_filetbl[lcifd].return_version == 1) {
00884           return( /* keep = */ 0 );
00885         }
00886             
00887   }
00888 
00889 
00890   return( /* keep = */ 1 );
00891 
00892 
00893 }
00894 
00895 
00896 
00897 /* --------------------------------------------------------------------------
00898  * Binary record input routine.
00899  *
00900  * Read the prepended record type, get space for the record, read in the
00901  * structure, read in any variable fields.
00902  * --------------------------------------------------------------------------
00903  */
00904 static int binary_record (cif_record, fd)
00905 struct Cif_generic **cif_record;                /* ptr to ptr to record */
00906 FILE *fd;                                                                       /* file descriptor of cif file */
00907 {
00908 
00909         int rtype, stat, size;
00910         register char *cp;
00911         struct Cif_generic *cr;
00912         struct Cif_generic rechdr;
00913         int keep = 1;
00914 
00915         do { /* look for a valid (ie what the user has asked for) record type */
00916           cp = (char *)&rechdr;
00917 
00918           if (fread (cp, sizeof(char), 1, fd) != 1) {
00919 
00920             if (feof(fd)) return (CIF_EOF);
00921             else return (CIF_SYSERR);
00922 
00923           }
00924 
00925           rtype = rechdr.rectype;
00926 
00927 
00928           if (rtype > CIF_MAXRECORD || valid_record[rtype] == NO) {
00929               return (CIF_BADFORM);
00930           }
00931 
00932           /* If we are not going to return this record, just make sure that we allocate
00933              the correct amount of space to read it in, ie make it equal what is on
00934              disk, not what we have to return; same for memset below. */
00935 
00936           if (_Cif_filetbl[lcifd].rmask[rtype] == '\0') {
00937 
00938             cr = *cif_record = (struct Cif_generic *) _Cif_space[lmode]
00939               (_Cif_structsize[rtype][_Cif_filetbl[lcifd].version],
00940                lcifd);
00941 
00942           }
00943           else {
00944 
00945             cr = *cif_record = (struct Cif_generic *) _Cif_space[lmode]
00946               (_Cif_structsize[rtype][_Cif_filetbl[lcifd].return_version],
00947                lcifd);
00948 
00949           }
00950 
00951           /* We are in trouble if there's no memory...best we can do is get out of here */
00952           if (cr == NULL)
00953             return (CIF_NOMEM);
00954 
00955 
00956           if (_Cif_filetbl[lcifd].rmask[rtype] == '\0') {
00957 
00958             (void) memset ((char *)cr, '\0',
00959                            _Cif_structsize[rtype][_Cif_filetbl[lcifd].version]);
00960 
00961           }
00962           else {
00963 
00964             (void) memset ((char *)cr, '\0',
00965                            _Cif_structsize[rtype][_Cif_filetbl[lcifd].return_version]);
00966 
00967           }
00968 
00969           cp = (char *)cr + 1;
00970           size = _Cif_shortsize[rtype][_Cif_filetbl[lcifd].version] - 1;
00971 
00972           /* If the cif versions are not equal, we have to map the data, ie some
00973              records changed between cif verions, became larger or values within
00974              them changed */
00975 
00976           /*
00977            * A new problem has been discovered recently in the structure of
00978            * the following code, but it is now too close to release to fix it
00979            * the right way.  A kludge work-around to the immediate problem
00980            * has been implemented and warning comments have been placed at a 
00981            * few critical places.  This note is left as a reminder to come 
00982            * back later and do the full fix.
00983            *
00984            * When the CIF file is version 3 and the user asks for version 2,
00985            * the following code reads in the fixed portion of the record,
00986            * calls _Cif_binary_map_version() to convert it to version 2, and
00987            * then passes the V2 record to _Cif_binread() to read in the 
00988            * "auxiliary" fields.  However, for some records like CIF_MESSAGE 
00989            * and CIF_FILE, _Cif_binread() needs information from the V3 record
00990            * to correctly read in the auxiliary fields.
00991            *
00992            * So, this code should be restructured to read in both the fixed
00993            * and auxiliary portions of the current record, and then call
00994            * _Cif_binary_map_version() to convert both parts.  This will
00995            * require lots of simple changes to _Cif_binread() and
00996            * _Cif_binary_map_version().  This was deemed to be too risky
00997            * since we are (in theory) getting close to field test.
00998            * TWH  7/13/95
00999            */
01000 
01001           if (_Cif_filetbl[lcifd].version == _Cif_filetbl[lcifd].return_version) {
01002 
01003             if (fread (cp, size, 1, fd) != 1)
01004               IO_ERROR;
01005           }
01006           else {  /* need to map between versions */
01007 
01008             /* create a temporary, static buffer in which to read data into, just
01009                in case the cif on disk is larger than the cif record to be returned
01010                (eg cif v2 on disk; application wants a v1) */
01011 
01012             if (_cif_map_buffer == (struct Cif_generic *) NULL)
01013               _cif_map_buffer = (struct Cif_generic *) malloc(CIF_MAX_SSIZE);
01014 
01015             (void) memset ((char *)_cif_map_buffer, '\0',
01016                 _Cif_shortsize[rtype][_Cif_filetbl[lcifd].return_version]);
01017 
01018             if (fread ((char *) _cif_map_buffer + 1, size, 1, fd) != 1)
01019               IO_ERROR;
01020 
01021             keep = _Cif_binary_map_version(rtype, _cif_map_buffer, cr);
01022 
01023           }
01024         
01025 
01026           cr->rectype = rtype;
01027 
01028           if ((stat = _Cif_binread (lcifd, rtype, cr, fd)) < 0)
01029             return (stat);
01030 
01031           /*
01032            * User doesn't want this record (or it's from a cif that the
01033            * application can't read (eg v2 for a v1 application ), so free
01034            * up this record space
01035            */
01036 
01037           if ((keep == 0 ||
01038                _Cif_filetbl[lcifd].rmask[rtype] == '\0') &&
01039               _Cif_filetbl[lcifd].mode == CIF_MEM_INDIV)
01040             Cif_Free(cr);
01041 
01042         }
01043         while (keep == 0 ||  _Cif_filetbl[lcifd].rmask[rtype] == '\0');
01044 
01045         return (rtype);
01046 
01047 }
01048  
01049 /* --------------------------------------------------------------------------
01050  * strlist process a list of string tokens and builds an array of pointers to
01051  * character strings.
01052  * --------------------------------------------------------------------------
01053  */
01054 
01055 static int strlist(args)
01056 register char ***args;                  /* number of strings in the list */
01057 {
01058         register int n, i, len;
01059         register char *c;
01060         char **aptr;
01061 
01062         aptr = NULL;
01063         if ( (n = atoi (token()) ) > 0) {
01064                 aptr = (char **)_Cif_space[lmode] (sizeof(char *)*n, lcifd);
01065                 if (aptr == NULL)
01066                         return (CIF_NOMEM);
01067                 for (i = 0; i < n; i++) {
01068                         c = token();
01069                         len = strlen (c);
01070                         aptr[i] = _Cif_space[lmode] (len+1, lcifd);
01071                         if (aptr[i] == NULL)
01072                                 return (CIF_NOMEM);
01073                         (void) strcpy (aptr[i], c);
01074                 }
01075         }
01076         *args = aptr;
01077         return(n);
01078 }
01079 
01080 /* --------------------------------------------------------------------------
01081  * llist processes a list of integer tokens and builds an array of pointers to
01082  * long ints.
01083  * --------------------------------------------------------------------------
01084  */
01085  
01086 static int llist(args, varargs)
01087 long **args;
01088 int *varargs;
01089 {
01090         register int n, i;
01091         register char *c;
01092         register long *aptr;
01093 
01094         c = token();
01095 
01096         /* String could be "*" (unknown) or "*n" for n known arguments
01097          * in a varargs list.  Set the varargs flag if "*" appears.
01098          */
01099 
01100         if (varargs != NULL) {
01101                 *varargs = 0;
01102                 if (*c == '*') {
01103                         *varargs = 1;
01104                         c++;
01105                 }
01106         }
01107 
01108         aptr = NULL;
01109         if ( (n = atoi (c) ) > 0) {
01110                 aptr = (long *)_Cif_space[lmode] (sizeof(long)*n, lcifd);
01111                 if (aptr == NULL)
01112                         return (CIF_NOMEM);
01113                 for (i = 0; i < n; i++)
01114                         aptr[i] = atoi (token());
01115         }
01116         *args = aptr;
01117         return(n);
01118 }
01119 
01120 /* --------------------------------------------------------------------------
01121  * filltype processes a C type descriptor.  The hex digit string and
01122  * associated id fields are returned as the basic type, qualifier, and
01123  * modifier structure.
01124  * --------------------------------------------------------------------------
01125  */
01126 
01127 static int filltype(basic, qual, tmod)
01128 register int *basic;
01129 register int *qual;
01130 register struct Cif_tmod **tmod;
01131 {
01132         register char *c;
01133         register char *c_array;
01134         register int len, n, i, funcseen = NO;
01135         static char digit[ ] = { '\0', '\0' };
01136         struct Cif_tmod *tm;
01137 
01138         /* Get the basic type (last two hex digits) and the qualifier (3rd from
01139          * last hex digit.  If that's all, return.
01140          */
01141 
01142         len = strlen(c = token());
01143 
01144         *basic = strtol(&c[len-2], (char **)NULL, 16);
01145         c[len-2] = '\0';
01146         *qual = strtol(&c[len-3], (char **)NULL, 16);
01147         c[len-3] = '\0';
01148         len -= 3;
01149         if (len <= 0) {
01150                 *tmod = (struct Cif_tmod *)NULL;
01151                 return (0);
01152         }
01153 
01154         /* Get Type modifiers -- 4th - 15th hex digits */
01155 
01156         tm= (struct Cif_tmod *)_Cif_space[lmode](sizeof(struct Cif_tmod)*len, lcifd);
01157         if (tm == NULL)
01158                 return (CIF_NOMEM);
01159 
01160         /* Go through the hex digits from left to right, grabbing another
01161          * token for each "array of" and all but the last "function
01162          * returning" modifier
01163          */
01164 
01165         for (i = 0; i < len; i++) {
01166                 digit[0] = c[i];
01167 
01168                 /* Save the modifier (hex. digit). */
01169 
01170                 tm[i].mod = n = strtol(digit, (char **)NULL, 16);
01171 
01172                 /* If an "array of" type, grab the next token
01173                  * which will be a dimension value.  If a "function
01174                  * returning" type, grab the next token ONLY if
01175                  * it is NOT the first "function returning" type.
01176                  * If it is the first "function returning" types,
01177                  * bypass getting the next token
01178                  */
01179 
01180                 if (n == CIF_TMC_ARRAY) {
01181                   c_array = token();
01182                   if (c_array != (char *) NULL)
01183                     if (atol(c_array) < 0)
01184                       tm[i].val = 0;
01185                     else
01186                       tm[i].val = atol(c_array);
01187                   else
01188                     tm[i].val = 0;
01189                 }
01190                 else if (n == CIF_TMC_FUNCNOPR || n == CIF_TMC_FUNCPRO) {
01191                         if (funcseen == NO) {
01192                                 funcseen = YES;
01193                                 tm[i].val = 0;
01194                                 continue;
01195                         }
01196                         else
01197                                 tm[i].val = atol(token());
01198                 }
01199                 else
01200                         tm[i].val = 0;
01201         }
01202         *tmod = tm;
01203         return (len);
01204 }
01205 
01206 /* --------------------------------------------------------------------------
01207  * ASCII record conversion routines
01208  *
01209  * Each routine accepts a pointer of the generic structure type, casts it to
01210  * the appropriate type, scans the current record via the "token" routine,
01211  * converts the tokens to binary values, and fills in the record structure.
01212  * --------------------------------------------------------------------------
01213  */
01214 
01215 static int ascii_c_const (con)
01216 struct Cif_c_const *con;
01217 {
01218         register char *c1, *c2;
01219         register long i;
01220 
01221         con->symid = atol (token());
01222         con->btype = strtol (token(), (char **)NULL, 16);
01223         c1 = token();
01224         i = strlen (c1) + 1;
01225         if (delim == SEPARATOR) {
01226                 c2 = token();
01227                 i += strlen (c2) + 1;
01228         }
01229         else
01230                 c2 = NULL;
01231         con->vlen = i;
01232         con->value = _Cif_space[lmode] (i, lcifd);
01233         if (con->value == NULL)
01234                 return (CIF_NOMEM);
01235         (void) strcpy (con->value, c1);
01236         if (c2 != NULL)
01237                 (void) strcpy (con->value+strlen(c1)+1, c2);
01238         return (CIF_C_CONST);
01239 
01240 }
01241 
01242 
01243 /* V1 and V2 differences : v2 has a tag id field; the symclass can have the value 5 */
01244 
01245 static int ascii_c_entry (ent)
01246 struct Cif_c_entry *ent;
01247 {
01248         register long i;
01249         register char *c;
01250         int basic, qual, v;
01251 
01252         /* If the user wants a v1 cif, then we need to use a different data
01253            structure */
01254 
01255         if (_Cif_filetbl[lcifd].return_version == 1) {
01256           struct Cif_c_entry_1 *ent1 = (struct Cif_c_entry_1 *) ent;
01257           int symclass;
01258 
01259           c = token();
01260           ent1->nlen = i = strlen (c);
01261           ent1->name = _Cif_space[lmode] (i+1, lcifd);
01262           if (ent1->name == NULL)
01263             return (CIF_NOMEM);
01264           (void) strcpy (ent1->name, c);
01265           ent1->symid = atol (token());
01266           ent1->ptype = atoi (token());
01267           symclass = atoi (token());
01268           if (_Cif_filetbl[lcifd].version != 1 && /* a v2 or greater cif */
01269               symclass == 5)
01270             symclass = 0;       /* symclass of 5 doesn't exist in a v1 cif */
01271 
01272           ent1->symclass = symclass;
01273           ent1->scope = atoi (token());
01274 
01275           /* No tag id in v1 c_entry record */
01276           /* ent1->tagid = atol (token()); */
01277 
01278           if (_Cif_filetbl[lcifd].version != 1) /* but we are reading a v2 cif
01279                                                   which has the tag id, so skip it */
01280             (void) token();
01281 
01282           c = token();
01283           ent1->retvalue = (*c == 'F') ? 0 : ((*c == 'T') ? 1 : 2);
01284           if ((i = llist(&(ent1->argids), &v)) < 0)
01285             return (CIF_NOMEM);
01286           ent1->nargs = i;
01287           ent1->varargs = v;
01288           if ((i = filltype(&basic, &qual, &(ent1->mods))) < 0)
01289             return (CIF_NOMEM);
01290           ent1->nmods = i;
01291           ent1->qual = qual;
01292           ent1->btype = basic;
01293 
01294         }
01295         else {  /* User wants a v2 cif */
01296 
01297           c = token();
01298           ent->nlen = i = strlen (c);
01299           ent->name = _Cif_space[lmode] (i+1, lcifd);
01300           if (ent->name == NULL)
01301             return (CIF_NOMEM);
01302           (void) strcpy (ent->name, c);
01303           ent->symid = atol (token());
01304           ent->ptype = atoi (token());
01305           ent->symclass = atoi (token());
01306           ent->scope = atoi (token());
01307 
01308           if (_Cif_filetbl[lcifd].version != 1) /* v1 cif doesn't have a tag id */
01309             ent->tagid = atol (token());
01310           /* else the tagid value has already been set to zero */
01311 
01312           c = token();
01313           ent->retvalue = (*c == 'F') ? 0 : ((*c == 'T') ? 1 : ((*c == 'I') ? 3 : 2));
01314           if ((i = llist(&(ent->argids), &v)) < 0)
01315             return (CIF_NOMEM);
01316           ent->nargs = i;
01317           ent->varargs = v;
01318           if ((i = filltype(&basic, &qual, &(ent->mods))) < 0)
01319             return (CIF_NOMEM);
01320           ent->nmods = i;
01321           ent->qual = qual;
01322           ent->btype = basic;
01323           if (delim == SEPARATOR) {
01324               ent->link = atol(token());
01325           }
01326         }
01327 
01328         return (CIF_C_ENTRY);
01329 }
01330 
01331 
01332 
01333 static int ascii_c_entry_end (ent_end)
01334 struct Cif_c_entry_end *ent_end;
01335 {
01336         register long i;
01337         register char *c;
01338 
01339         c = token();
01340         ent_end->nlen = i = strlen (c);
01341         ent_end->name = _Cif_space[lmode] (i+1, lcifd);
01342         if (ent_end->name == NULL)
01343                 return (CIF_NOMEM);
01344         (void) strcpy (ent_end->name, c);
01345         ent_end->symid = atol (token());
01346         ent_end->fid = atol (token());
01347         ent_end->strline = atol (token());
01348         ent_end->endline = atol (token());
01349 
01350         return (CIF_C_ENTRY_END);
01351 }
01352 
01353 
01354 static int ascii_c_lint_directive (lint_dir)
01355 struct Cif_c_lint_directive *lint_dir;
01356 {
01357   register long i;
01358   register char *c;
01359 
01360   c = token();
01361   lint_dir->nlen = i = strlen (c);
01362   lint_dir->name = _Cif_space[lmode] (i+1, lcifd);
01363   if (lint_dir->name == NULL)
01364     return (CIF_NOMEM);
01365   (void) strcpy (lint_dir->name, c);
01366   lint_dir->val = atol (token());
01367   lint_dir->objid = atol (token());
01368   lint_dir->fid = atol (token());
01369   lint_dir->strline = atol (token());
01370   lint_dir->strpos = atol (token());
01371   lint_dir->endline = atol (token());
01372   lint_dir->endpos = atol (token());
01373 
01374   return (CIF_C_LINT_DIRECTIVE);
01375 }
01376 
01377 static int ascii_c_macro_def (macro_def)
01378 struct Cif_c_macro_def *macro_def;
01379 {
01380   register long i;
01381   register char *c;
01382 
01383   macro_def->symid = atol (token());
01384 
01385   c = token();
01386   macro_def->nlen = i = strlen (c);
01387   macro_def->name = _Cif_space[lmode] (i+1, lcifd);
01388   if (macro_def->name == NULL)
01389     return (CIF_NOMEM);
01390   (void) strcpy (macro_def->name, c);
01391 
01392   macro_def->fid = atol (token());
01393   macro_def->strline = atol (token());
01394   macro_def->strpos = atol (token());
01395   macro_def->endline = atol (token());
01396   macro_def->endpos = atol (token());
01397 
01398   return (CIF_C_MACRO_DEF);
01399 }
01400 
01401 static int ascii_c_macro_undef (macro_undef)
01402 struct Cif_c_macro_undef *macro_undef;
01403 {
01404 
01405   macro_undef->symid = atol (token());
01406   macro_undef->fid = atol (token());
01407   macro_undef->line = atol (token());
01408   macro_undef->cpos = atol (token());
01409 
01410   return (CIF_C_MACRO_UNDEF);
01411 }
01412 
01413 static int ascii_c_macro_usage (macro_use)
01414 struct Cif_c_macro_usage *macro_use;
01415 {
01416   macro_use->useid = atol(token());
01417   macro_use->symid = atol(token());
01418   macro_use->fid = atol(token());
01419   macro_use->strline = atol(token());
01420   macro_use->strpos = atol(token());
01421   macro_use->endline = atol(token());
01422   macro_use->endpos = atol(token());
01423 
01424   return (CIF_C_MACRO_USAGE);
01425 }
01426 
01427 
01428 /* v1 to v2 difference : v2 has a message code value */
01429 
01430 static int ascii_c_message (msg)
01431 struct Cif_c_message *msg;
01432 {
01433         register char *c;
01434         register int tmp;
01435 
01436         /* If the user wants a v1 cif, then we need to use a different data
01437            structure */
01438 
01439         if (_Cif_filetbl[lcifd].return_version == 1) {
01440           struct Cif_c_message_1 *msg1 = (struct Cif_c_message_1 *) msg;
01441 
01442           msg1->severity = atoi(token());
01443           msg1->msgno = atoi(token());
01444 
01445           /* No message code in v1 c_message record */
01446 
01447           /* msg->msgcode = atoi(token()); */
01448 
01449           if (_Cif_filetbl[lcifd].version != 1) /* but we are reading a v2 cif
01450                                                   which has the message code, so skip it */
01451             (void) token();
01452 
01453           msg1->fid = atol(token());
01454           msg1->fline = atol(token());
01455           c = token();
01456           msg1->flinesuf = *c;
01457           msg1->incid = atol(token());
01458           msg1->iline = atol(token());
01459           tmp = strlist(&(msg1->args));
01460           if (tmp < 0)
01461             return (CIF_NOMEM);
01462           msg1->nargs = tmp;
01463         }
01464         else { /* a v2 cif */
01465 
01466           msg->severity = atoi(token());
01467           msg->msgno = atoi(token());
01468 
01469           if (_Cif_filetbl[lcifd].version != 1) /* v1 cif doesn't have a message code id */
01470             msg->msgcode = atoi(token());
01471           /* else the message code value has already been set to zero */
01472 
01473           msg->fid = atol(token());
01474           msg->fline = atol(token());
01475           c = token();
01476           msg->flinesuf = *c;
01477           msg->incid = atol(token());
01478           msg->iline = atol(token());
01479           tmp = strlist(&(msg->args));
01480           if (tmp < 0)
01481             return (CIF_NOMEM);
01482           msg->nargs = tmp;
01483         }
01484 
01485         return (CIF_C_MESSAGE);
01486 }
01487 
01488 
01489 
01490 /* v1 to v2 difference :  entity value 11 -> 10, 12 -> 11 */
01491 
01492 static int ascii_c_object (obj)
01493 struct Cif_c_object *obj;
01494 {
01495         register char *c;
01496         register int i;
01497         int basic, qual;
01498 
01499 
01500         /*
01501          * If the user wants a v1 cif, then we need to use a different data
01502          * structure
01503          */
01504 
01505         if (_Cif_filetbl[lcifd].return_version == 1) {
01506           struct Cif_c_object_1 *obj1 = (struct Cif_c_object_1 *) obj;
01507 
01508           c = token();
01509           obj1->nlen = i = strlen (c);
01510           obj1->name = _Cif_space[lmode] (i+1, lcifd);
01511           if (obj1->name == NULL)
01512               return (CIF_NOMEM);
01513           (void) strcpy (obj1->name, c);
01514           obj1->symid = atol (token());
01515           obj1->entity = atoi (token());
01516 
01517           /* v1 entity values 11 and 12 map to v2 enity values of 10 and 11 */
01518 
01519           if (_Cif_filetbl[lcifd].version != 1 &&
01520               (obj1->entity == 10 || obj1->entity == 11))
01521               obj1->entity ++;
01522 
01523           obj1->symclass = atoi (token());
01524           obj1->scope = atoi (token());
01525           obj1->tagid = atol (token());
01526           obj1->psymid = atol (token());
01527           obj1->size = atoi (token());
01528           if ((i = filltype(&basic, &qual, &(obj1->mods))) < 0)
01529               return (CIF_NOMEM);
01530           obj1->nmods = i;
01531           obj1->qual = qual;
01532           obj1->btype = basic;
01533 
01534       }
01535         else { /* return a v2 cif */
01536 
01537             c = token();
01538             obj->nlen = i = strlen (c);
01539             obj->name = _Cif_space[lmode] (i+1, lcifd);
01540             if (obj->name == NULL)
01541                 return (CIF_NOMEM);
01542             (void) strcpy (obj->name, c);
01543             obj->symid = atol (token());
01544             obj->entity = atoi (token());
01545 
01546             /* v1 entity values 11 and 12 map to v2 enity values of 10 and 11 */
01547 
01548             if (_Cif_filetbl[lcifd].version == 1 &&
01549                 (obj->entity == 11 || obj->entity == 12))
01550                 obj->entity --;
01551 
01552             obj->symclass = atoi (token());
01553             obj->scope = atoi (token());
01554             obj->tagid = atol (token());
01555             obj->psymid = atol (token());
01556             obj->size = atoi (token());
01557             if ((i = filltype(&basic, &qual, &(obj->mods))) < 0)
01558                 return (CIF_NOMEM);
01559             obj->nmods = i;
01560             obj->qual = qual;
01561             obj->btype = basic;
01562 
01563             if (delim == SEPARATOR) {
01564                 obj->link = atol(token());
01565             }
01566         }
01567 
01568         return (CIF_C_OBJECT);
01569 }
01570 
01571 static int ascii_c_opts (opt)
01572 struct Cif_c_opts *opt;
01573 {
01574         register char *c;
01575         register long i;
01576 
01577         c = token();
01578         opt->nlen = i = strlen (c);
01579         opt->name = _Cif_space[lmode] (i+1, lcifd);
01580         if (opt->name == NULL)
01581                 return (CIF_NOMEM);
01582         (void) strcpy (opt->name, c);
01583         (void) strcpy (opt->bopts, token());
01584         opt->msglev = atoi(token());
01585         opt->truncval = atoi (token());
01586         opt->debug = *token();
01587         (void) strncpy (opt->report, token(), sizeof(opt->report));
01588         opt->atsklev = atoi (token());
01589         opt->inlnlev = atoi (token());
01590         opt->sclrlev = atoi (token());
01591         opt->vctrlev = atoi (token());
01592         if ((i = strlist(&(opt->incs))) < 0)
01593                 return (CIF_NOMEM);
01594         opt->nincs = i;
01595         if ((i = strlist(&(opt->defs))) < 0)
01596                 return (CIF_NOMEM);
01597         opt->ndefs = i;
01598         if ((i = strlist(&(opt->udefs))) < 0)
01599                 return (CIF_NOMEM);
01600         opt->nudefs = i;
01601 
01602         return (CIF_C_OPTS);
01603 }
01604 
01605 
01606 /* v1 to v2 difference :  entity value 10 -> 9 */
01607 
01608 static int ascii_c_tag (tag)
01609 struct Cif_c_tag *tag;
01610 {
01611         register char *c;
01612         register long i;
01613         int basic, qual;
01614         register int tmp;
01615 
01616         c = token();
01617         tag->nlen = i = strlen(c);
01618         tag->name = _Cif_space[lmode] (i+1, lcifd);
01619         if (tag->name == NULL)
01620                 return (CIF_NOMEM);
01621         (void) strcpy (tag->name, c);
01622         tag->tagid = atol (token());
01623         tag->entity = atoi (token());
01624 
01625         /* v1 entity value 10 maps to v2 enity values of 9 */
01626 
01627         if (_Cif_filetbl[lcifd].version == 1 &&
01628             _Cif_filetbl[lcifd].return_version != 1 &&
01629             tag->entity == 10)
01630           tag->entity = 9;
01631         else
01632           if (_Cif_filetbl[lcifd].version != 1 &&
01633               _Cif_filetbl[lcifd].return_version == 1 &&
01634               tag->entity == 9)
01635             tag->entity = 10;
01636 
01637         tag->size = atoi (token());
01638         tmp = llist(&(tag->memids), (int *) NULL);
01639         if (tmp < 0)
01640           return (CIF_NOMEM);
01641         tag->nmems = tmp;
01642         tmp = filltype(&basic, &qual, &(tag->mods));
01643         if (tmp < 0)
01644           return (CIF_NOMEM);
01645         tag->nmods = tmp;
01646         tag->qual = qual;
01647         tag->btype = basic;
01648 
01649         return (CIF_C_TAG);
01650 }
01651 
01652 static int ascii_callsite (cs)
01653 struct Cif_callsite *cs;
01654 {
01655 
01656         register long i;
01657         register int nargs;
01658 
01659         cs->entryid = atol (token());
01660         cs->fid = atol (token());
01661         cs->line = atol (token());
01662         cs->cpos = atol (token());
01663         if ( (nargs = cs->nargs = atoi (token())) > 0) {
01664                 cs->argids = (long *)_Cif_space[lmode] (sizeof(long)*nargs, lcifd);
01665                 if (cs->argids == NULL)
01666                         return (CIF_NOMEM);
01667                 i = 0;
01668                 while (i < nargs)
01669                         cs->argids[i++] = atol (token());
01670         }
01671         if (delim == SEPARATOR)
01672                 cs->valused = (*token() == 'F' ? 0 : 1);
01673         return (CIF_CALLSITE);
01674 
01675 }
01676 
01677 static int ascii_cifhdr (hdr)
01678 struct Cif_cifhdr *hdr;
01679 {
01680 
01681         (void) token(); /* must be "cif" */
01682         hdr->version = atoi (token()+1);
01683         hdr->lang = _Cif_filetbl[lcifd].lang = atoi (token());
01684 
01685         /*
01686          * Set the srcfid, set earlier from looking
01687          * ahead to the srcfile record
01688          * in v1, this used to be an unused field, so no need to mask out
01689          */
01690 
01691         hdr->srcfid = _Cif_filetbl[lcifd].srcfid;
01692 
01693         /*
01694          * F90 has a slightly different cif_usage record, so use a different
01695          * parse routine
01696          */
01697 
01698 #ifndef CRAY2
01699         if (_Cif_filetbl[lcifd].lang == CIF_LG_F90) {
01700           ascii_record[CIF_USAGE] = ascii_f90_usage;
01701         }
01702         else {
01703           ascii_record[CIF_USAGE] = ascii_usage;
01704         }
01705 #endif /* CRAY2 */
01706 
01707         (void) strcpy (hdr->cvers, token());
01708         (void) strcpy (hdr->date, token());
01709         (void) strcpy (hdr->time, token());
01710         (void) strcpy (hdr->group, token());
01711         hdr->msgfid = atol (token());
01712 
01713         /*
01714          * We need this so that when returning a v1 cif, we do not
01715          * return the file record associated with the message catalog
01716          */
01717 
01718         global_msgfid = hdr->msgfid;
01719         (void) strncpy (hdr->machname, token(), 8);
01720         (void) strncpy (hdr->hostcpu, token(), 8);
01721         hdr->hostcpu[8] = '\0'; /* make sure that the string is terminated */
01722         hdr->canpos = _Cif_filetbl[lcifd].seek;
01723         hdr->form = ASCII_CIF_FORMAT;
01724         hdr->form = 0;
01725         return (CIF_CIFHDR);
01726 
01727 }
01728 
01729 static int ascii_comblk (cb)
01730 struct Cif_comblk *cb;
01731 {
01732 
01733         register char *c;
01734         register long i;
01735 
01736         /*
01737          * If the user wants a v1 cif, then we need to use a different data
01738          * structure
01739          */
01740 
01741         if (_Cif_filetbl[lcifd].return_version == 1) {
01742           struct Cif_comblk_1 *cb1 = (struct Cif_comblk_1 *) cb;
01743 
01744           c = token();
01745           cb1->nlen = i = strlen (c);
01746           cb1->name = _Cif_space[lmode] (i+1, lcifd);
01747           if (cb1->name == NULL)
01748             return (CIF_NOMEM);
01749           (void) strcpy (cb1->name, c);
01750           cb1->symid = atol (token());
01751           cb1->cbtype = atoi (token());
01752           cb1->length = atol (token());
01753 
01754           /* No distribution code in v1 c_message record */
01755 
01756           /* cb1->dist = atoi(token()); */
01757 
01758           if (_Cif_filetbl[lcifd].version != 1) /* but we are reading a v2 cif
01759                                                   which has the distribution code, so skip it */
01760             (void) token();
01761 
01762         }
01763 
01764         else { /* version 2 cif */
01765 
01766           c = token();
01767           cb->nlen = i = strlen (c);
01768           cb->name = _Cif_space[lmode] (i+1, lcifd);
01769           if (cb->name == NULL)
01770             return (CIF_NOMEM);
01771           (void) strcpy (cb->name, c);
01772           cb->symid = atol (token());
01773           cb->cbtype = atoi (token());
01774           cb->length = atol (token());
01775 
01776           if (_Cif_filetbl[lcifd].version != 1) { /* v1 cif doesn't have a distribution code id */
01777             c = token();
01778             if (c != (char *) NULL &&
01779                 *c != (char) NULL)
01780               cb->dist = atoi(c);
01781           }
01782           /* else the distribution code value has already been set to zero */
01783 
01784         }
01785 
01786         return (CIF_COMBLK);
01787 
01788 }
01789 
01790 
01791 static int ascii_const (con)
01792 struct Cif_const *con;
01793 {
01794         register int i;
01795         register char *c;
01796         register long attr;
01797         register int n;
01798 
01799         /*
01800          * If the user wants a v1 cif, then we need to use a different data
01801          * structure
01802          */
01803 
01804         if (_Cif_filetbl[lcifd].return_version == 1) {
01805           struct Cif_const_1 *con1 = (struct Cif_const_1 *) con;
01806 
01807           c = token();
01808           con1->nlen = i= strlen (c);
01809           con1->name = _Cif_space[lmode] (i+1, lcifd);
01810           if (con1->name == NULL)
01811             return (CIF_NOMEM);
01812           (void) strcpy (con1->name, c);
01813           con1->symid = atol (token());
01814           con1->dtype = atoi (token());
01815           if (con1->dtype == 100)
01816             con1->dtype = 0;
01817           else
01818             (con1->dtype)++;
01819 
01820           /* get constant value - multiple values not implemented */
01821 
01822           if ( (con1->nvalues = atoi (token())) == 1) {
01823 
01824             con1->vlen = i = strlen (c = token());
01825             con1->value = _Cif_space[lmode] (i+1, lcifd);
01826             if (con1->value == NULL)
01827               return (CIF_NOMEM);
01828             (void) strcpy (con1->value, c);
01829 
01830           }
01831 
01832           /* get attributes */
01833 
01834           attr = strtol (token(), (char **)NULL, 16);
01835           con1->imptype = ((attr & CO_ATTR_IMPTYPE) != 0);
01836 
01837           /* No original form flag in v1 c_message record */
01838 
01839           /* cb1->origform = 0; */
01840           /* cb1->olen = 0; */
01841           /* cb1->oform = (char *) NULL; */
01842 
01843           if (_Cif_filetbl[lcifd].version != 1) { /* but we are reading a v2 cif
01844                                                    * which has the original flag/value,
01845                                                    * so skip them
01846                                                    */
01847             (void) token();
01848             if (delim == SEPARATOR)
01849               (void) token();
01850           }
01851         }
01852         else { /* version 2 cif */
01853           c = token();
01854           con->nlen = i= strlen (c);
01855           con->name = _Cif_space[lmode] (i+1, lcifd);
01856           if (con->name == NULL)
01857             return (CIF_NOMEM);
01858           (void) strcpy (con->name, c);
01859           con->symid = atol (token());
01860           con->dtype = atoi (token());
01861           if (con->dtype == 100)
01862             con->dtype = 0;
01863           else
01864             (con->dtype)++;
01865 
01866           /* get constant value - multiple values not implemented */
01867 
01868           if ( (con->nvalues = atoi (token())) == 1) {
01869             con->vlen = i = strlen (c = token());
01870             con->value = _Cif_space[lmode] (i+1, lcifd);
01871             if (con->value == NULL)
01872               return (CIF_NOMEM);
01873             (void) strcpy (con->value, c);
01874           }
01875 
01876           /* get attributes */
01877 
01878           attr = strtol (token(), (char **)NULL, 16);
01879           con->imptype = ((attr & CO_ATTR_IMPTYPE) != 0);
01880           /* If character type, read the character length */
01881           if ((attr & CO_ATTR_CHAR) != 0) {
01882             (void) token();
01883           }
01884 
01885           /* Read the dimensions - not stored in the cif */
01886           if ((attr & CO_ATTR_DIM) != 0) {
01887             n = atoi(token());
01888 
01889             while (n > 0) {
01890               (void) token();  /* discard lower bound */
01891               (void) token();  /* discard upper bound */
01892               n--;
01893             }
01894 
01895           }
01896 
01897           if (_Cif_filetbl[lcifd].version != 1) { /* v1 cif doesn't have the oiginal
01898                                                    * form fields
01899                                                    */
01900             con->origform = atoi(token());
01901             if (con->origform) {
01902               c = token();
01903               con->olen = i = strlen (c);
01904               con->oform = _Cif_space[lmode] (i+1, lcifd);
01905               if (con->oform == NULL)
01906                 return (CIF_NOMEM);
01907               (void) strcpy (con->oform, c);
01908             }
01909           }
01910           /* else the original form fields have already been set to zero */
01911         }
01912         return (CIF_CONST);
01913 
01914 }
01915 
01916 
01917 static int ascii_edopts (eo)
01918 struct Cif_edopts *eo;
01919 {
01920 
01921         eo->opts = strtol (token(), (char **)NULL, 16);
01922         return (CIF_EDOPTS);
01923 
01924 }
01925 
01926 static int ascii_entry (entry)
01927 struct Cif_entry *entry;
01928 {
01929 
01930         register char *c;
01931         register long i, len;
01932 
01933         c = token();
01934         entry->nlen = len = strlen (c);
01935         entry->name = _Cif_space[lmode] (len+1, lcifd);
01936         if (entry->name == NULL)
01937                 return (CIF_NOMEM);
01938         (void) strcpy (entry->name, c);
01939         entry->symid = atol (token());
01940         entry->etype = atol (token());
01941         entry->dtype = atol (token());
01942         if (entry->dtype == 100)
01943                 entry->dtype = 0;
01944         else
01945                 (entry->dtype)++;
01946 
01947         /* get argument ids */
01948 
01949         if ( (len = atoi (token())) >= 0) {
01950                 entry->valargs = 1;
01951                 if (len > 0) {
01952                         entry->nargs = len;
01953                         entry->argids = (long *)_Cif_space[lmode] (sizeof(long)*len, lcifd);
01954                         if (entry->argids == NULL)
01955                                 return (CIF_NOMEM);
01956                         for (i = 0; i < len; i++)
01957                                 (entry->argids)[i] = atol (token());
01958                 }
01959         }
01960 
01961         /* get attributes */
01962 
01963         i = strtol (token(), (char **)NULL, 16);
01964         entry->recur = ((i & EN_ATTR_RECUR) != 0);
01965         entry->stmtfunc = ((i & EN_ATTR_STMTF) != 0);
01966         entry->extrn = ((i & EN_ATTR_EXTERN) != 0);
01967         entry->intrin = ((i & EN_ATTR_INTRIN) != 0);
01968         entry->imptype = ((i & EN_ATTR_IMPTYPE) != 0);
01969         if ((i & EN_ATTR_CHAR) != 0)
01970                 entry->charlen = atol (token());
01971         else
01972                 entry->charlen = 0;
01973         return (CIF_ENTRY);
01974 
01975 }
01976 
01977 static int ascii_file (file)
01978 struct Cif_file *file;
01979 {
01980 
01981         register char *c;
01982         register long len;
01983 
01984         if (_Cif_filetbl[lcifd].return_version == 3) {
01985 
01986           c = token();
01987 
01988           file->nlen = len = strlen (c);
01989           file->name = _Cif_space[lmode] (len+1, lcifd);
01990           if (file->name == NULL)
01991               return (CIF_NOMEM);
01992           (void) strcpy (file->name, c);
01993           file->fid = atol (token());
01994 
01995           if (delim == SEPARATOR) {
01996 
01997             c = token();
01998 
01999             file->onlen = len = strlen (c);
02000             file->oname = _Cif_space[lmode] (len+1, lcifd);
02001             if (file->oname == NULL)
02002                 return (CIF_NOMEM);
02003             (void) strcpy (file->oname, c);
02004           }
02005         }
02006         else { /* returning a v<3 CIF */
02007 
02008           struct Cif_file_1 *file1 = (struct Cif_file_1 *) file;
02009 
02010           c = token();
02011 
02012           file1->nlen = len = strlen (c);
02013           file1->name = _Cif_space[lmode] (len+1, lcifd);
02014           if (file1->name == NULL)
02015               return (CIF_NOMEM);
02016           (void) strcpy (file1->name, c);
02017           file1->fid = atol (token());
02018 
02019           /*
02020            * If we are returning a version 1 cif and the file is the
02021            * message catalog, which didn't appear in v1 cif's
02022            * then don't return it.
02023            */
02024           if (_Cif_filetbl[lcifd].lang == CIF_LG_F77 &&
02025               file1->fid == global_msgfid &&
02026               _Cif_filetbl[lcifd].return_version == 1) {
02027             return ( CIF_MAXRECORD );  /* flags an invalid record */
02028           }
02029 
02030 
02031         }
02032         return (CIF_FILE);
02033 
02034 }
02035 
02036 static int ascii_include (inc)
02037 struct Cif_include *inc;
02038 {
02039 
02040         inc->srcid = atol (token());
02041         inc->line = atol (token());
02042         inc->cpos = atol (token());
02043         inc->incid = atol (token());
02044         return (CIF_INCLUDE);
02045 
02046 }
02047 
02048 static int ascii_label (label)
02049 struct Cif_label *label;
02050 {
02051 
02052         register char *c;
02053         register long i;
02054 
02055         c = token();
02056         label->nlen = i = strlen (c);
02057         label->name = _Cif_space[lmode] (i+1, lcifd);
02058         if (label->name == NULL)
02059                 return (CIF_NOMEM);
02060         (void) strcpy (label->name, c);
02061         label->symid = atol (token());
02062         label->ltype = atoi (token());
02063         return (CIF_LABEL);
02064 
02065 }
02066 
02067 static int ascii_loop (loop)
02068 struct Cif_loop *loop;
02069 {
02070 
02071         loop->lptype = atol (token());
02072         loop->sfid = atol (token());
02073         loop->strline = atol (token());
02074         loop->strcpos = atol (token());
02075         loop->efid = atol (token());
02076         loop->endline = atol (token());
02077         loop->endcpos = atol (token());
02078         if (delim == SEPARATOR)
02079                 loop->symid = atol (token());
02080         if (delim == SEPARATOR)
02081                 loop->labelid = atol (token());
02082         return (CIF_LOOP);
02083 
02084 }
02085 
02086 /* --- Fortran machine characteristic values mask --- */
02087 #define NFORTCHARS                      8
02088 #define CIF_MCF_TAILGT          0x01
02089 #define CIF_MCF_BDM                     0x02
02090 #define CIF_MCF_CIGS                    0x04
02091 #define CIF_MCF_EMA                     0x08
02092 #define CIF_MCF_READVL          0x10
02093 #define CIF_MCF_VPOP                    0x20
02094 #define CIF_MCF_VRECUR          0x40
02095 #define CIF_MCF_AVL                     0x80
02096 
02097 
02098 /*
02099  * Note. Machine characteristic became unnecessarily complicated
02100  * between C, F77 and F90 and from v1 to v2. F77 started off with
02101  * it's own subset of the full set. C provided a more complete
02102  * set of characteristics, so for F77 we mapped the compiler
02103  * provided list to be what C gave. In v2, F77 now provides
02104  * the more complete list (as do F90 for the start). But if a user
02105  * requires a v1 cif from a v2 cif, we have to mask out thouse bits
02106  * not previosly available.
02107  */
02108 
02109 
02110 static int ascii_mach_char (mc)
02111 struct Cif_mach_char *mc;
02112 {
02113         int i;
02114         long valmask;
02115 
02116         static int fort_mc[NFORTCHARS] = {
02117                 CIF_MCF_TAILGT,
02118                 CIF_MCF_BDM,
02119                 CIF_MCF_CIGS,
02120                 CIF_MCF_EMA,
02121                 CIF_MCF_READVL,
02122                 CIF_MCF_VPOP,
02123                 CIF_MCF_VRECUR,
02124                 CIF_MCF_AVL
02125         };
02126         static int gen_mc[NFORTCHARS] = {
02127                 CIF_MC_TAILGT,
02128                 CIF_MC_BDM,
02129                 CIF_MC_CIGS,
02130                 CIF_MC_EMA,
02131                 CIF_MC_READVL,
02132                 CIF_MC_VPOP,
02133                 CIF_MC_VRECUR,
02134                 CIF_MC_AVL
02135         };
02136 
02137         /*
02138          * If the user wants a v1 cif, then we need to use a different data
02139          * structure
02140          */
02141 
02142         if (_Cif_filetbl[lcifd].return_version == 1) {
02143           struct Cif_mach_char_1 *mc1 = (struct Cif_mach_char_1 *) mc;
02144 
02145           for (i = 0; i < 16; i++) mc1->cpuname[i] = '\0';
02146           (void) strcpy (mc1->cpuname, token());
02147           mc1->memspeed = atoi (token());
02148           mc1->memsize = atol (token());
02149           valmask = strtol (token(), (char **)NULL, 16);
02150 
02151           /*
02152            * If we are reading a cft77 v2 cif, we may have more characteristics
02153            * then v1 could handle, and they will be in different bit places
02154            */
02155 
02156           if (_Cif_filetbl[lcifd].lang == CIF_LG_F77) {
02157             if (_Cif_filetbl[lcifd].version != 1) {
02158               /*
02159                * We have the correct bits, but some of them could
02160                * not be set in v1, so mask those out
02161                */
02162 #ifdef CRAY2
02163               /*
02164                * On a Cray2, TAILGT was 0x01 in v1, it is now 0x02
02165                * It is the only valid cray2 value for a v1 cif
02166                */
02167               if (mc1->valmask | CIF_MC_TAILGT_1)  {
02168                 mc1->valmask = CIF_MC_TAILGT;
02169               }
02170               else {
02171                 mc1->valmask = 0;
02172               }
02173 #else  /* Non-Cray2 have more bits to mask out */
02174               mc1->valmask = valmask & CIF_MC_MASK;
02175 #endif /* CRAY2 */
02176 
02177           }
02178             else { /*
02179                     * v1 to v1; map what the cif is giving to the correct
02180                     * return values, consistent with C
02181                     */
02182               mc1->valmask = 0;
02183               for (i = 0; i < NFORTCHARS; i++)
02184                 if (valmask & fort_mc[i]) mc1->valmask |= gen_mc[i];
02185             }
02186         }
02187           else {  /* valmask is already okay for C and F90 */
02188               mc1->valmask = valmask;
02189           }
02190           /*
02191            * No : number of banks, number of cpus, instruction buffer size
02192            * clock period, number of cluster registers or bank busy time
02193            * fields in a version 1 cif
02194            */
02195 
02196           if (_Cif_filetbl[lcifd].version != 1 &&
02197               delim == SEPARATOR) {
02198             /*
02199              * but we are reading a v2 cif which has them
02200              */
02201             (void) token();     /* num banks */
02202             (void) token();     /* num cpus */
02203             (void) token();     /* instruction buffer size */
02204             (void) token();     /* clock period */
02205             (void) token();     /* number of cluster register sets */
02206             (void) token();     /* bank busy time */
02207           }
02208 
02209       }
02210         else { /* return a v2 cif */
02211 
02212           (void) strcpy (mc->cpuname, token());
02213 
02214           mc->memspeed = atoi (token());
02215           mc->memsize = atol (token());
02216           valmask = strtol (token(), (char **)NULL, 16);
02217 
02218           /*
02219            * we only have to go through this mapping business for F77,
02220            * C and F90 provide the right machine characteristics
02221            */
02222 
02223           if (_Cif_filetbl[lcifd].lang == CIF_LG_F77) {
02224 
02225             /*
02226              * if it's a v1 cif, we have to map the bits still from
02227              * what the compiler provides to what we want
02228              */
02229 
02230             if (_Cif_filetbl[lcifd].version == 1) {
02231               mc->valmask = 0;
02232               for (i = 0; i < NFORTCHARS; i++)
02233                 if (valmask & fort_mc[i]) mc->valmask |= gen_mc[i];
02234             }
02235             else /*
02236                   * v2 to v2, so just propagate the value which F77 is
02237                   * now provide in the correct format
02238                   */
02239               mc->valmask = valmask;
02240           }
02241           else { /* C and F90 provide the correct format directly */
02242             mc->valmask = valmask;
02243           }
02244 
02245           /* Read the extra v2 cif fields (if present) :
02246            * number of banks, number of cpus, instruction buffer size
02247            * clock period, number of cluster registers or bank busy time
02248            */
02249 
02250           if (_Cif_filetbl[lcifd].version != 1 &&
02251               delim == SEPARATOR) {
02252 
02253             mc->numbanks = atol (token());
02254             mc->numcpus = atol (token());
02255             mc->instbufsize = atol (token());
02256             mc->clockperiod = atol (token());
02257             mc->numclregs = atol (token());
02258             mc->bankbusytime = atol (token());
02259 
02260             if (delim == SEPARATOR)
02261               mc->tbitlen = atoi (token());
02262 
02263           }
02264           /* else they will already be set to zero */
02265 
02266         }
02267 
02268         return (CIF_MACH_CHAR);
02269 
02270 }
02271 
02272 static int ascii_message (msg)
02273 struct Cif_message *msg;
02274 {
02275         register char *c;
02276         register long i;
02277         register int tmp;
02278 
02279         if (_Cif_filetbl[lcifd].return_version <= 2) {
02280           struct Cif_message_1 *msg1 = (struct Cif_message_1 *) msg;
02281 
02282           msg1->severity = atoi (token());
02283           msg1->msgno = atol (token());
02284           msg1->fid = atol (token());
02285           msg1->uline = atol (token());
02286           msg1->cpos = atoi (token());
02287           msg1->fline = atol (token());
02288           tmp = strlist(&(msg1->args));
02289           if (tmp < 0)
02290             return (CIF_NOMEM);
02291           msg1->nargs = tmp;
02292 
02293         }
02294         else { /* Version 3 CIF */
02295           msg->severity = atoi (token());
02296           msg->msgno = atol (token());
02297           msg->fid = atol (token());
02298           msg->uline = atol (token());
02299           msg->cpos = atoi (token());
02300           msg->fline = atol (token());
02301           tmp = strlist(&(msg->args));
02302           if (tmp < 0)
02303             return (CIF_NOMEM);
02304           msg->nargs = tmp;
02305 
02306           /* scoping unit names are only present in V3 CIF's */
02307           if (_Cif_filetbl[lcifd].version >= 3 &&
02308               delim == SEPARATOR) {
02309 
02310             c = token();
02311             msg->nlen = i = strlen(c);
02312             msg->name = _Cif_space[lmode] (i+1, lcifd);
02313             if (msg->name == NULL)
02314                 return (CIF_NOMEM);
02315             (void) strcpy (msg->name, c);
02316             if (delim == SEPARATOR) {
02317                 msg->order = atoi(token());
02318                 if (delim == SEPARATOR) {
02319                   msg->flags = atoi(token());
02320                   if (delim == SEPARATOR) {
02321                     msg->pfid = atol(token());
02322                   }
02323                 }
02324               }
02325           }
02326           else {
02327                 /* We are creating a version 3 record from a Version 2
02328                  * CIF. If this is subsequently passed to a Version 2
02329                  * reading application, the pfid is copied into the fid
02330                  * as that is the more correct value for V3 CIF's. When
02331                  * messages are coming from inlined files the V2 CIF's
02332                  * do not contain enough information to make use of the
02333                  * two fid values, so the pfid value should be used.
02334                  * Once we have a V3 record, libcif can not tell if this
02335                  * came from a valid V3 CIF or from a V2->V3 mapping
02336                  * process, so it is appropriate to copy the fid into
02337                  * the pfid to allow it to be copied back again later
02338                  * if necessary.
02339                  */
02340                 msg->pfid = msg->fid;
02341         }
02342 
02343         }
02344 
02345         return (CIF_MESSAGE);
02346 }
02347 
02348 static int ascii_misc_opts (mo)
02349 struct Cif_misc_opts *mo;
02350 {
02351         register int i, j;
02352         register char *c;
02353         register int tmp;
02354 
02355         /*
02356          * If the user wants a v1 cif, then we need to use a different data
02357          * structure
02358          */
02359 
02360         if (_Cif_filetbl[lcifd].return_version == 1) {
02361           struct Cif_misc_opts_1 *mo1 = (struct Cif_misc_opts_1 *) mo;
02362 
02363           mo1->malloc = atoi (token());
02364           mo1->intlen = atoi (token());
02365           mo1->msglvl = atoi (token());
02366           mo1->vopt = atoi (token());
02367           mo1->amode = atoi (token ());
02368           mo1->trunc = atoi (token ());
02369           mo1->truncval = atoi (token());
02370           tmp = llist(&(mo1->msgno), (int *) NULL);
02371           if (tmp < 0)
02372             return (CIF_NOMEM);
02373           mo1->nmsgs = tmp;
02374 
02375           tmp = strlist (&(mo1->cdirs));
02376           if (tmp < 0)
02377             return (CIF_NOMEM);
02378 
02379           mo1->ncdirs = tmp;
02380           c = token();
02381           if ((mo1->onlen = i = strlen (c)) > 0) {
02382             mo1->objname = _Cif_space[lmode] (i+1, lcifd);
02383             if (mo1->objname == NULL)
02384               return (CIF_NOMEM);
02385             (void) strcpy (mo1->objname, c);
02386           }
02387           c = token();
02388           if (c != (char *) NULL && (mo1->cnlen = i = strlen (c)) > 0) {
02389             mo1->calname = _Cif_space[lmode] (i+1, lcifd);
02390             if (mo1->calname == NULL)
02391               return (CIF_NOMEM);
02392             (void) strcpy (mo1->calname, c);
02393           }
02394 
02395           c = token();
02396           if (delim == SEPARATOR) {
02397             if (c != (char *) NULL && (mo1->inlen = i = strlen (c)) > 0) {
02398               mo1->inname = _Cif_space[lmode] (i+1, lcifd);
02399               if (mo1->inname == NULL)
02400                 return (CIF_NOMEM);
02401               (void) strcpy (mo1->inname, c);
02402             }
02403           }
02404 
02405           /*
02406            * No listing name, cif option, input length, run-time checking
02407            * or include file fields in a version 1 cif
02408            */
02409 
02410           if (_Cif_filetbl[lcifd].version != 1) { /*
02411                                                    * but we are reading a v2 cif
02412                                                    * which has the distribution and geometry
02413                                                    * fields, so skip them
02414                                                    */
02415             (void) token();     /* listing name */
02416             (void) token();     /* cif option */
02417             (void) token();     /* input length */
02418             (void) token();     /* run-time checking */
02419             i = atoi(token());  /* number includes */
02420             for (j = 0; j < i; j++)
02421               (void) token();   /* include file name */
02422           }
02423 
02424 
02425         }
02426 
02427         else { /* return a v2 cif */
02428 
02429           mo->malloc = atoi (token());
02430           mo->intlen = atoi (token());
02431           mo->msglvl = atoi (token());
02432           mo->vopt = atoi (token());
02433           mo->amode = atoi (token ());
02434           mo->trunc = atoi (token ());
02435           mo->truncval = atoi (token());
02436           tmp = llist(&(mo->msgno), (int *) NULL);
02437           if (tmp < 0)
02438             return (CIF_NOMEM);
02439           mo->nmsgs = tmp;
02440 
02441           tmp = strlist (&(mo->cdirs));
02442           if (tmp < 0)
02443             return (CIF_NOMEM);
02444           mo->ncdirs = tmp;
02445 
02446           c = token();
02447           if ((mo->onlen = i = strlen (c)) > 0) {
02448             mo->objname = _Cif_space[lmode] (i+1, lcifd);
02449             if (mo->objname == NULL)
02450               return (CIF_NOMEM);
02451             (void) strcpy (mo->objname, c);
02452           }
02453 
02454           c = token();
02455           if ((mo->cnlen = i = strlen (c)) > 0) {
02456             mo->calname = _Cif_space[lmode] (i+1, lcifd);
02457             if (mo->calname == NULL)
02458               return (CIF_NOMEM);
02459             (void) strcpy (mo->calname, c);
02460           }
02461 
02462           c = token();
02463           if (delim == SEPARATOR) {
02464             if ((mo->inlen = i = strlen (c)) > 0) {
02465               mo->inname = _Cif_space[lmode] (i+1, lcifd);
02466               if (mo->inname == NULL)
02467                 return (CIF_NOMEM);
02468               (void) strcpy (mo->inname, c);
02469             }
02470           }
02471 
02472           /* Read the extra v2 cif fields */
02473 
02474           if (_Cif_filetbl[lcifd].version != 1) {
02475 
02476             c = token();
02477             if (delim == SEPARATOR) {
02478               if (c != (char *) NULL && (mo->llen = i = strlen (c)) > 0) {
02479                 mo->lname = _Cif_space[lmode] (i+1, lcifd);
02480                 if (mo->lname == NULL)
02481                   return (CIF_NOMEM);
02482                 (void) strcpy (mo->lname, c);
02483               }
02484             }
02485 
02486             mo->cifopt = strtol (token(), (char **)NULL, 16);
02487             mo->inputlen = atoi(token());
02488             mo->runtime = strtol (token(), (char **)NULL, 16);
02489             tmp = strlist (&(mo->incdirs));
02490             if (tmp < 0)
02491               return (CIF_NOMEM);
02492             mo->numincs = tmp;
02493             }
02494 
02495           }
02496 
02497 
02498         return (CIF_MISC_OPTS);
02499 
02500 }
02501 
02502 static int ascii_namelist (nl)
02503 struct Cif_namelist *nl;
02504 {
02505 
02506         register long i;
02507         register char *c;
02508 
02509         c = token();
02510         nl->nlen = i = strlen (c);
02511         nl->name = _Cif_space[lmode] (i+1, lcifd);
02512         if (nl->name == NULL)
02513                 return (CIF_NOMEM);
02514         (void) strcpy (nl->name, c);
02515         nl->symid = atol (token());
02516         if ((nl->nids = atoi (token())) > 0) {
02517                 nl->ids = (long *) _Cif_space[lmode] (sizeof(long)*nl->nids, lcifd);
02518                 if (nl->ids == NULL)
02519                         return (CIF_NOMEM);
02520                 for (i = 0; i < (int) nl->nids; i++)
02521                         (nl->ids)[i] = atol (token());
02522 
02523         }
02524         return (CIF_NAMELIST);
02525 
02526 }
02527 
02528 static int ascii_nd_msg (nmsg)
02529 struct Cif_nd_msg *nmsg;
02530 {
02531         register int tmp;
02532 
02533         nmsg->severity = atoi (token());
02534         nmsg->msgno = atol (token());
02535         nmsg->fid = atol (token());
02536         nmsg->fline = atol (token());
02537         nmsg->cpos = atoi (token());
02538         nmsg->uline = atol (token());
02539         (void) strncpy (nmsg->group, token(), 16);
02540         nmsg->msgfid = atol (token());
02541 
02542         tmp = strlist(&(nmsg->args));
02543         if (tmp < 0)
02544           return (CIF_NOMEM);
02545         nmsg->nargs = tmp;
02546         return (CIF_ND_MSG);
02547 
02548 }
02549 
02550 
02551 /* v1 to v2 difference : v2 has a distribution field and geometry field added */
02552 
02553 static int ascii_object (obj)
02554 struct Cif_object *obj;
02555 {
02556 
02557         register char *c;
02558         register long i, attr;
02559         struct Cif_dim *dim;
02560 
02561         /*
02562          * If the user wants a v1 cif, then we need to use a different data
02563          * structure
02564          */
02565 
02566         if (_Cif_filetbl[lcifd].return_version == 1) {
02567           struct Cif_object_1 *obj1 = (struct Cif_object_1 *) obj;
02568 
02569           c = token();
02570           if ((obj1->nlen = i = strlen (c)) > 0) {
02571             obj1->name = _Cif_space[lmode] (i+1, lcifd);
02572             if (obj1->name == NULL)
02573               return (CIF_NOMEM);
02574             (void) strcpy (obj1->name, c);
02575           }
02576           else
02577             obj1->name = NULL;
02578           obj1->symid = atol (token());
02579           obj1->dtype = atoi (token());
02580           if (obj1->dtype == 100)
02581             obj1->dtype = 0;
02582           else
02583             (obj1->dtype)++;
02584 
02585           obj1->symclass = atoi (token());
02586 
02587           obj1->storage = atol (token());
02588           if ((i = atol (token())) >= 0) {
02589             obj1->valoffset = 1;
02590             obj1->offset = i;
02591           }
02592 
02593 
02594           /* get attributes */
02595           attr = strtol (token(), (char **)NULL, 16);
02596           obj1->aarray = ((attr & CO_ATTR_AUTO) != 0);
02597           obj1->equiv = ((attr & CO_ATTR_EQUIV) != 0);
02598           obj1->data = ((attr & CO_ATTR_DATA) != 0);
02599           obj1->save = ((attr & CO_ATTR_SAVE) != 0);
02600           obj1->imptype = ((attr & CO_ATTR_IMPTYPE) != 0);
02601 
02602           /*
02603            * PE_RESIDENT, pointee, array and geometry 
02604            * declaration fields didn't exist on v1, so don't set them
02605            */
02606 
02607           /*
02608             obj1->peresident == ((attr & CO_ATTR_PE_RESIDENT) != 0);
02609             obj1->pointee == ((attr & CO_ATTR_POINTEE) != 0);
02610             obj1->array_dec == ((attr & CO_ATTR_ARRAY_DEC) != 0);
02611             obj1->geom_dec == ((attr & CO_ATTR_GEOM_DEC) != 0);
02612             */
02613 
02614           if ((attr & CO_ATTR_CHAR) != 0) {
02615             c = token ();
02616             if (*c == '*')
02617               obj1->cltype = 1;
02618             else
02619               obj1->charlen = atol (c);
02620           }
02621           else
02622             obj1->charlen = 0;
02623           if ((attr & CO_ATTR_DIM) == 0)
02624             obj1->ndims = 0;
02625           else {
02626             obj1->ndims = atoi (token());
02627             dim = obj1->dim = (struct Cif_dim *)_Cif_space[lmode]
02628               (sizeof(struct Cif_dim)*obj1->ndims, lcifd);
02629             if (dim == NULL)
02630               return (CIF_NOMEM);
02631             for (i=0; i < (int) obj1->ndims; i++) {
02632               c = token ();
02633               if (*c == 'E')
02634                 dim->ltype = CIF_DM_EXPR;
02635               else if (*c == '*')
02636                 dim->ltype = CIF_DM_ASSUMED;
02637               else {
02638                 dim->ltype = CIF_DM_CONSTANT;
02639                 dim->lower = atol (c);
02640               }
02641               c = token ();
02642               if (*c == 'E')
02643                 dim->utype = CIF_DM_EXPR;
02644               else if (*c == '*')
02645                 dim->utype = CIF_DM_ASSUMED;
02646               else {
02647                 dim->utype = CIF_DM_CONSTANT;
02648                 dim->upper = atol (c);
02649               }
02650               dim++;
02651             }
02652           }
02653 
02654           /* No distribution, geometry id or pointer id in v1 cif */
02655 
02656           /* obj1->distribution = atoi(token()); */
02657           /* obj1->geomid = atoi(token()); */
02658           /* obj1->pointer = atoi(token()); */
02659 
02660           if (_Cif_filetbl[lcifd].version != 1) { /*
02661                                                    * but we are reading a v2 cif
02662                                                    * which has the distribution and geometry
02663                                                    * fields, so skip them
02664                                                    */
02665             (void) token();  /* distribution, geometry id and pointer id */
02666             (void) token();  /* they wouldn't all be there, but that's okay, */
02667             (void) token();  /* token will just keep giving the eol */
02668           }
02669 
02670         }
02671         else {  /* returning a v2 cif */
02672           c = token();
02673           if ((obj->nlen = i = strlen (c)) > 0) {
02674             obj->name = _Cif_space[lmode] (i+1, lcifd);
02675             if (obj->name == NULL)
02676               return (CIF_NOMEM);
02677             (void) strcpy (obj->name, c);
02678           }
02679           else
02680             obj->name = NULL;
02681           obj->symid = atol (token());
02682           obj->dtype = atoi (token());
02683           if (obj->dtype == 100)
02684             obj->dtype = 0;
02685           else
02686             (obj->dtype)++;
02687 
02688           obj->symclass = atoi (token());
02689           obj->storage = atol (token());
02690           if ((i = atol (token())) >= 0) {
02691             obj->valoffset = 1;
02692             obj->offset = i;
02693           }
02694 
02695 
02696           /* get attributes */
02697           attr = strtol (token(), (char **)NULL, 16);
02698           obj->aarray = ((attr & CO_ATTR_AUTO) != 0);
02699           obj->equiv = ((attr & CO_ATTR_EQUIV) != 0);
02700           obj->data = ((attr & CO_ATTR_DATA) != 0);
02701           obj->save = ((attr & CO_ATTR_SAVE) != 0);
02702           obj->imptype = ((attr & CO_ATTR_IMPTYPE) != 0);
02703 
02704           /*
02705            * There's no chance of getting these next few from a v1 cif, but
02706            * it does no harm to look
02707            */
02708 
02709           obj->peresident = ((attr & CO_ATTR_PE_RESIDENT) != 0);
02710           obj->pointee = ((attr & CO_ATTR_POINTEE) != 0);
02711           obj->arraydec = ((attr & CO_ATTR_ARRAY_DEC) != 0);
02712           obj->geomdec = ((attr & CO_ATTR_GEOM_DEC) != 0);
02713 
02714           if ((attr & CO_ATTR_CHAR) != 0) {
02715             c = token ();
02716             if (*c == '*')
02717               obj->cltype = 1;
02718             else
02719               obj->charlen = atol (c);
02720           }
02721           else
02722             obj->charlen = 0;
02723           if ((attr & CO_ATTR_DIM) == 0)
02724             obj->ndims = 0;
02725           else {
02726             obj->ndims = atoi (token());
02727             dim = obj->dim = (struct Cif_dim *)_Cif_space[lmode]
02728               (sizeof(struct Cif_dim)*obj->ndims, lcifd);
02729 
02730             if (dim == NULL)
02731               return (CIF_NOMEM);
02732             for (i=0; i < (int) obj->ndims; i++) {
02733               c = token ();
02734               if (*c == 'E')
02735                 dim->ltype = CIF_DM_EXPR;
02736               else if (*c == '*')
02737                 dim->ltype = CIF_DM_ASSUMED;
02738               else {
02739                 dim->ltype = CIF_DM_CONSTANT;
02740                 dim->lower = atol (c);
02741               }
02742               c = token ();
02743               if (*c == 'E')
02744                 dim->utype = CIF_DM_EXPR;
02745               else if (*c == '*')
02746                 dim->utype = CIF_DM_ASSUMED;
02747               else {
02748                 dim->utype = CIF_DM_CONSTANT;
02749                 dim->upper = atol (c);
02750               }
02751               dim++;
02752             }
02753           }
02754 
02755           if (_Cif_filetbl[lcifd].version != 1) { /*
02756                                                    * v1 cif doesn't have the distribution,
02757                                                    * geometry id or pointer fields
02758                                                    */
02759             /*
02760              * read the token first to see of it is not null; it is possible that
02761              * a non-MPP compkiler will not put out these fields, or they will be NULL
02762              */
02763 
02764             c = token();
02765             if (c != (char *) NULL &&
02766                 *c != (char) NULL)
02767               obj->dist = atoi(c);
02768 
02769             if (obj->pointee || obj->dist == 3) {   /* 3 is SHARED dimensional */
02770               c = token();
02771               if (c != (char *) NULL &&
02772                   *c != (char) NULL)
02773                 if (obj->pointee)
02774                   obj->pointer = atol(c);
02775               else
02776                 obj->geomid = atol(c);
02777             }
02778           /* else the distribution, geometry and pointer fields have already been set to zero */
02779 
02780           }
02781         }
02782 
02783         return (CIF_OBJECT);
02784 
02785 }
02786 
02787 static int ascii_opt_opts (oo)
02788 struct Cif_opt_opts *oo;
02789 {
02790         /*
02791          * If the user wants a v1 cif, then we need to use a different data
02792          * structure
02793          */
02794 
02795         if (_Cif_filetbl[lcifd].return_version == 1) {
02796           struct Cif_opt_opts_1 *oo1 = (struct Cif_opt_opts_1 *) oo;
02797 
02798           oo1->values = strtol (token(), (char **)NULL, 16);
02799 
02800           /* No inline level field in a v1 cif */
02801 
02802           if (_Cif_filetbl[lcifd].version != 1) { /*
02803                                                    * but we are reading a v2 cif
02804                                                    * which has the inline level field
02805                                                    */
02806             if (oo1->values == CIF_OOF_INLINE)
02807               (void) token();
02808           }
02809 
02810 
02811         }
02812         else {  /* returning a v2 cif */
02813 
02814           oo->values = strtol (token(), (char **)NULL, 16);
02815 
02816           if (_Cif_filetbl[lcifd].version != 1) { /*
02817                                                    * v1 cif doesn't have the inline level field
02818                                                    */
02819             if (oo->values == CIF_OOF_INLINE)
02820               oo->inlevel = atoi(token());
02821           }
02822         }
02823 
02824         return (CIF_OPT_OPTS);
02825 
02826 }
02827 
02828 static int ascii_srcfile (src)
02829 struct Cif_srcfile *src;
02830 {
02831 
02832         src->fid = atol (token());
02833         if (delim == SEPARATOR)
02834                 src->form = atoi (token());
02835         else
02836                 src->form = 0;
02837         return (CIF_SRCFILE);
02838 
02839 }
02840 
02841 static int ascii_transform (tran)
02842 struct Cif_transform *tran;
02843 {
02844         tran->type = atoi(token());
02845         tran->fid = atol(token());
02846         tran->line = atol(token());
02847 
02848         return (CIF_TRANSFORM);
02849 
02850 }
02851 
02852 static int ascii_stmt_type (stmt)
02853 struct Cif_stmt_type *stmt;
02854 {
02855 
02856         stmt->type = atol (token());
02857         stmt->fid = atol (token());
02858         stmt->line = atol (token());
02859         stmt->cpos = atol (token());
02860 
02861         if ( *ntoken != 0 )
02862             stmt->efid = atol (token());
02863         if ( *ntoken != 0 )
02864             stmt->eline = atol (token());
02865         if ( *ntoken != 0 )
02866             stmt->ecpos = atol (token());
02867 
02868         /* If we are returning a version 1 cif and the stmt type == CDIR,
02869          * then don't return it as version 1 cif's didn't have cdir stmts
02870          */
02871 
02872         if (stmt->type == CIF_TP_CDIR &&
02873             _Cif_filetbl[lcifd].return_version == 1) {
02874           return ( CIF_MAXRECORD );  /* flags an invalid record */
02875 
02876         }
02877 
02878         return (CIF_STMT_TYPE);
02879 
02880 }
02881 
02882 static int ascii_summary (sum)
02883 struct Cif_summary *sum;
02884 {
02885 
02886         (void) strcpy (sum->level, token());
02887         (void) strcpy (sum->gdate, token());
02888         (void) strcpy (sum->gtime, token());
02889         (void) strcpy (sum->ctime, token());
02890         sum->fldlen = atol (token());
02891         sum->nlines = atol (token());
02892         sum->csize = atol (token());
02893         sum->dsize = atol (token());
02894         return (CIF_SUMMARY);
02895 
02896 }
02897 
02898 
02899 static int ascii_cdir (cdir)
02900 struct Cif_cdir *cdir;
02901 {
02902         register long i;
02903 
02904         cdir->type = atoi (token());
02905         cdir->fid = atol (token());
02906         cdir->line = atol (token());
02907         cdir->cpos = atol (token());
02908         cdir->nids = atoi (token());
02909         if (cdir->nids > 0) {
02910           cdir->ids = (long *)_Cif_space[lmode] (sizeof(long)*(cdir->nids), lcifd);
02911           for (i = 0; i < (int) cdir->nids; i++) {
02912             cdir->ids[i] = atol (token());
02913           }
02914         }
02915 
02916         return(CIF_CDIR);
02917 }
02918 
02919 
02920 static int ascii_cdir_doshared (dos)
02921 struct Cif_cdir_doshared *dos;
02922 {
02923         register long i;
02924         char *c;
02925 
02926         dos->type = atoi (token());
02927         c = token();
02928         dos->random = (*c == '1' ? 1 : 0);
02929         dos->fid = atol (token());
02930         dos->line = atol (token());
02931         dos->cpos = atol (token());
02932         c = token();
02933         if (*c == 'E') {
02934           dos->mexpr = 1;
02935           dos->m = atol(c);
02936         }
02937         else {
02938           dos->mexpr = 0;
02939         }
02940         dos->mfid = atol (token());
02941         dos->mline = atol (token());
02942         dos->mcpos = atol (token());
02943         dos->nids = atoi (token());
02944         if (dos->nids > 0) {
02945           dos->ids = (long *)_Cif_space[lmode] (sizeof(long)*(dos->nids), lcifd);
02946           for (i = 0; i < (int) dos->nids; i++) {
02947             dos->ids[i] = atol (token());
02948           }
02949         }
02950 
02951         return(CIF_CDIR_DOSHARED);
02952 }
02953 
02954 static int ascii_geometry (geom)
02955 struct Cif_geometry *geom;
02956 {
02957         register long i;
02958         char *c;
02959         struct Cif_geometry_dim *dim;
02960 
02961         c = token();
02962         if (c != (char *) NULL) {
02963                 geom->nlen = i = strlen (c);
02964                 geom->name = _Cif_space[lmode] (i+1, lcifd);
02965                 if (geom->name == NULL)
02966                         return (CIF_NOMEM);
02967                 (void) strcpy (geom->name, c);
02968         }
02969         else
02970                 geom->nlen = 0;
02971 
02972         geom->geomid = atol (token());
02973         geom->ndims = atoi (token());
02974         dim = geom->dim = (struct Cif_geometry_dim *)_Cif_space[lmode]
02975                                 (sizeof(struct Cif_geometry_dim)*geom->ndims, lcifd);
02976         if (dim == NULL)
02977                 return (CIF_NOMEM);
02978         for (i=0; i < (int) geom->ndims; i++) {
02979                 dim->dist = strtol (token(), (char **)NULL, 16);
02980                 c = token();
02981                 if (*c == 'E') {
02982                         dim->wtype = 1;
02983                         dim->weight = 0;
02984                 }
02985                 else {
02986                         dim->wtype = 0;
02987                         dim->weight = atol (c);
02988                 }
02989                 dim->wfid = atol (token());
02990                 dim->wline = atol (token());
02991                 dim->wcpos = atol (token());
02992                 c = token();
02993                 if (*c == 'E') {
02994                         dim->btype = 1;
02995                         dim->bsize = 0;
02996                 }
02997                 else {
02998                         dim->btype = 0;
02999                         dim->bsize = atol (c);
03000                 }
03001                 dim->bfid = atol (token());
03002                 dim->bline = atol (token());
03003                 dim->bcpos = atol (token());
03004 
03005                 dim++;
03006       }
03007 
03008         return(CIF_GEOMETRY);
03009 }
03010 
03011 static int ascii_continuation (co)
03012 struct Cif_continuation *co;
03013 {
03014         char *c;
03015 
03016         c = token();
03017         co->type = (*c == '0' ? 0 : 1);
03018         co->fid = atol (token());
03019         co->line = atol (token());
03020         co->cpos = atol (token());
03021 
03022         return(CIF_CONTINUATION);
03023 }
03024 
03025 
03026 #ifndef CRAY2
03027 static int ascii_f90_callsite (cs)
03028 struct Cif_f90_callsite *cs;
03029 {
03030         register int i, j;
03031         register int nargs;
03032         register char *c;
03033 
03034         cs->entryid = atol (token());
03035         cs->scopeid = atol (token());
03036         cs->fid = atol (token());
03037         cs->line = atol (token());
03038         cs->cpos = atol (token());
03039         cs->procid = atol (token());
03040         nargs = atoi (token());
03041         if (nargs >= 0)
03042             cs->nargs = nargs;
03043         else
03044             cs->nargs = 0;
03045         if (nargs > 0) {
03046 
03047                 cs->argids = (long *)_Cif_space[lmode] (sizeof(long)*nargs, lcifd);
03048                 if (cs->argids == NULL)
03049                         return (CIF_NOMEM);
03050 
03051                 cs->nmembs = (int *)_Cif_space[lmode] (sizeof(long)*nargs, lcifd);
03052                 if (cs->nmembs == NULL)
03053                         return (CIF_NOMEM);
03054 
03055                 cs->membs = (long **)_Cif_space[lmode] (sizeof(long *)*nargs, lcifd);
03056                 if (cs->membs == NULL)
03057                         return (CIF_NOMEM);
03058 
03059                 for (i = 0; i < nargs; i++) {
03060                         c = token();
03061                         /*
03062                          * If the symbol id has members, this field will be %,
03063                          * otherwise it is the symbol id
03064                          */
03065 
03066                         if (*c == '%') {
03067                           cs->nmembs[i] = atoi (token()) - 1;
03068                           cs->argids[i] = atol (token());
03069 
03070                           cs->membs[i] =
03071                             (long *)_Cif_space[lmode] (sizeof(long)*cs->nmembs[i], lcifd);
03072                           for (j = 0; j < cs->nmembs[i]; j++) {
03073                             cs->membs[i][j] = atol( token());
03074                           }
03075                           /* now read the lst '%'...redundant really, but no harm done */
03076                           (void) token();
03077                       }
03078                         else {
03079                             cs->argids[i] = atol (c);
03080                             cs->nmembs[i] = 0;
03081                             cs->membs[i] = 0;
03082                         }
03083                     }
03084 
03085         }
03086 
03087 /*  Not issued by the f90 compiler at all; left for comment only
03088         if (delim == SEPARATOR)
03089                 cs->valused = (*token() == 'F' ? 0 : 1);
03090 */
03091 
03092         if (delim == SEPARATOR) {
03093 
03094             cs->rank = 1;
03095             cs->ranks = (int *)_Cif_space[lmode] (sizeof(int)*nargs, lcifd);
03096             if (cs->ranks == NULL)
03097                 return (CIF_NOMEM);
03098 
03099             for (i = 0; i < nargs; i++) {
03100                 cs->ranks[i] = atoi(token());
03101             }
03102         }
03103 
03104         return(CIF_F90_CALLSITE);
03105 }
03106 
03107 
03108 static int ascii_f90_comblk (cb)
03109 struct Cif_f90_comblk *cb;
03110 {
03111         register char *c;
03112         register long i;
03113 
03114         c = token();
03115         cb->nlen = i = strlen (c);
03116         cb->name = _Cif_space[lmode] (i+1, lcifd);
03117         if (cb->name == NULL)
03118                 return (CIF_NOMEM);
03119         (void) strcpy (cb->name, c);
03120         cb->symid = atol (token());
03121         cb->scopeid = atol (token());
03122         cb->cbtype = atoi (token());
03123         cb->moduleid = atol (token());
03124         cb->length = atol (token());
03125         c = token();
03126         if (c != (char *) NULL)
03127             cb->dist = atoi (c);
03128 
03129         return(CIF_F90_COMBLK);
03130 }
03131 
03132 
03133 static int ascii_f90_const (con)
03134 struct Cif_f90_const *con;
03135 {
03136         register int i;
03137         register char *c;
03138 
03139         con->symid = atol (token());
03140         con->scopeid = atol (token());
03141         c = token();
03142         con->aggregate = (*c == '0' ? 0 : 1);
03143 
03144         /* get constant value - multiple values not implemented */
03145         
03146         if (con->aggregate == 0) {
03147                 con->vlen = i = strlen (c = token());
03148                 con->value = _Cif_space[lmode] (i+1, lcifd);
03149                 if (con->value == NULL)
03150                         return (CIF_NOMEM);
03151                 (void) strcpy (con->value, c);
03152               }
03153         else
03154           c = token();  /* pass the null field for an aggregate constant */
03155 
03156         con->fid = atol (token());
03157         con->strline = atol (token());
03158         con->strpos = atol (token());
03159         con->endline = atol (token());
03160         con->endpos = atol (token());
03161 
03162         return(CIF_F90_CONST);
03163 }
03164 
03165 
03166 static int ascii_f90_entry (entry)
03167 struct Cif_f90_entry *entry;
03168 {
03169 
03170         register char *c;
03171         register long i, len;
03172 
03173         c = token();
03174         entry->nlen = len = strlen (c);
03175         entry->name = _Cif_space[lmode] (len+1, lcifd);
03176         if (entry->name == NULL)
03177                 return (CIF_NOMEM);
03178         (void) strcpy (entry->name, c);
03179         entry->symid = atol (token());
03180         entry->scopeid = atol (token());
03181         entry->etype = atoi (token());
03182         entry->ptype = atoi (token());
03183 
03184         /* get attributes */
03185 
03186         i = strtol (token(), (char **)NULL, 16);
03187         entry->defined = ((i & F90_EN_ATTR_DEFINED) != 0);
03188         entry->intblock = ((i & F90_EN_ATTR_INT_BLOCK) != 0);
03189         entry->referenced = ((i & F90_EN_ATTR_REFERENCED) != 0);
03190         entry->optional = ((i & F90_EN_ATTR_OPTIONAL) != 0);
03191         entry->priv = ((i & F90_EN_ATTR_PRIVATE) != 0);
03192         entry->recur = ((i & F90_EN_ATTR_RECUR) != 0);
03193         entry->useassoc = ((i & F90_EN_ATTR_USE) != 0);
03194 
03195         entry->stmtfunc = (entry->etype == CIF_F90_ET_STMT);
03196 
03197         entry->resultid = atol (token());
03198 
03199         entry->moduleid = atol (token());
03200 
03201         /* get argument ids */
03202 
03203         if ( (len = atoi (token())) >= 0) {
03204                 entry->valargs = 1;
03205                 if (len > 0) {
03206                         entry->nargs = len;
03207                         entry->argids = (long *)_Cif_space[lmode] (sizeof(long)*len, lcifd);
03208                         if (entry->argids == NULL)
03209                                 return (CIF_NOMEM);
03210                         for (i = 0; i < len; i++)
03211                                 (entry->argids)[i] = atol (token());
03212                 }
03213         }
03214         else {
03215           entry->valargs = 0;
03216           entry->nargs = 0;
03217         }
03218 
03219 
03220         return(CIF_F90_ENTRY);
03221 }
03222 
03223 
03224 static int ascii_f90_loop (loop)
03225 struct Cif_f90_loop *loop;
03226 {
03227   int statementID;
03228 
03229         loop->scopeid = atol (token());
03230         loop->lptype = atol (token());
03231         loop->sfid = atol (token());
03232         loop->strline = atol (token());
03233         loop->strcpos = atol (token());
03234         loop->efid = atol (token());
03235         loop->endline = atol (token());
03236         loop->endcpos = atol (token());
03237         if (delim == SEPARATOR)
03238                 loop->symid = atol (token());
03239         if (delim == SEPARATOR)
03240                 loop->labelid = atol (token());
03241         if (delim == SEPARATOR)
03242                 loop->nameid = atol (token());
03243         /* Statement id's for the loops terminating line */
03244         if (delim == SEPARATOR) {
03245           statementID = atol (token());
03246           /* No space to hold the statement field directly, so we have
03247            * to split the value into 3 parts - done magically through
03248            * setStmtid */
03249           setStmtid(loop, statementID);
03250         }
03251 
03252         return(CIF_F90_LOOP);
03253 }
03254 
03255 
03256 static int ascii_f90_derived_type (dt)
03257 struct Cif_f90_derived_type *dt;
03258 {
03259         register char *c;
03260         register long i, len;
03261 
03262         if (_Cif_filetbl[lcifd].return_version <= 2) {
03263           struct Cif_f90_derived_type_2 *dt2 = (struct Cif_f90_derived_type_2 *) dt;
03264 
03265           c = token();
03266           dt2->nlen = len = strlen (c);
03267           dt2->name = _Cif_space[lmode] (len+1, lcifd);
03268           if (dt2->name == NULL)
03269               return (CIF_NOMEM);
03270           (void) strcpy (dt2->name, c);
03271           dt2->symid = atol (token());
03272           dt2->scopeid = atol (token());
03273           dt2->dervtype = atol (token());
03274 
03275           dt2->flag = strtol (token(), (char **)NULL, 16);
03276 
03277           dt2->sequence = ((dt2->flag & CIF_DRT_SEQUENCE) != 0);
03278           dt2->defprivate = ((dt2->flag & CIF_DRT_PRIVATE) != 0);
03279           dt2->comprivate = ((dt2->flag & CIF_DRT_COMP_PRIVATE) != 0);
03280 
03281           /* read member ids */
03282 
03283           if ( (len = atoi (token())) > 0) {
03284             dt2->nmembs = len;
03285             dt2->memids = (long *)_Cif_space[lmode] (sizeof(long)*len, lcifd);
03286             if (dt2->memids == NULL)
03287                 return (CIF_NOMEM);
03288             for (i = 0; i < len; i++)
03289                 (dt2->memids)[i] = atol (token());
03290           }
03291         }
03292         else { /* version 3 CIF record, as above + add the moduleid field */
03293           c = token();
03294           dt->nlen = len = strlen (c);
03295           dt->name = _Cif_space[lmode] (len+1, lcifd);
03296           if (dt->name == NULL)
03297               return (CIF_NOMEM);
03298           (void) strcpy (dt->name, c);
03299           dt->symid = atol (token());
03300           dt->scopeid = atol (token());
03301           dt->dervtype = atol (token());
03302 
03303           dt->flag = strtol (token(), (char **)NULL, 16);
03304 
03305           dt->sequence = ((dt->flag & CIF_DRT_SEQUENCE) != 0);
03306           dt->defprivate = ((dt->flag & CIF_DRT_PRIVATE) != 0);
03307           dt->comprivate = ((dt->flag & CIF_DRT_COMP_PRIVATE) != 0);
03308 
03309           /* read member ids */
03310 
03311           if ( (len = atoi (token())) > 0) {
03312             dt->nmembs = len;
03313             dt->memids = (long *)_Cif_space[lmode] (sizeof(long)*len, lcifd);
03314             if (dt->memids == NULL)
03315                 return (CIF_NOMEM);
03316             for (i = 0; i < len; i++)
03317                 (dt->memids)[i] = atol (token());
03318           }
03319 
03320           /* moduleid's are only present in V3 CIF's */
03321           if (_Cif_filetbl[lcifd].version >= 3 &&
03322               delim == SEPARATOR) {
03323             dt->moduleid = atol (token());
03324           }
03325         }
03326 
03327         return (CIF_F90_DERIVED_TYPE);
03328 }
03329 
03330 
03331 
03332 static int ascii_f90_label (label)
03333 struct Cif_f90_label *label;
03334 {
03335         register char *c;
03336         register long i;
03337 
03338         c = token();
03339         label->nlen = i = strlen (c);
03340         label->name = _Cif_space[lmode] (i+1, lcifd);
03341         if (label->name == NULL)
03342                 return (CIF_NOMEM);
03343         (void) strcpy (label->name, c);
03344         label->symid = atol (token());
03345         label->scopeid = atol (token());
03346         label->ltype = atoi (token());
03347 
03348         return(CIF_F90_LABEL);
03349 }
03350 
03351 
03352 static int ascii_f90_namelist (nl)
03353 struct Cif_f90_namelist *nl;
03354 {
03355         register long i;
03356         register char *c;
03357 
03358         c = token();
03359         nl->nlen = i = strlen (c);
03360         nl->name = _Cif_space[lmode] (i+1, lcifd);
03361         if (nl->name == NULL)
03362                 return (CIF_NOMEM);
03363         (void) strcpy (nl->name, c);
03364         nl->symid = atol (token());
03365         nl->scopeid = atol (token());
03366         nl->moduleid = atol (token());
03367         if ((nl->nids = atoi (token())) > 0) {
03368                 nl->ids = (long *) _Cif_space[lmode] (sizeof(long)*nl->nids, lcifd);
03369                 if (nl->ids == NULL)
03370                         return (CIF_NOMEM);
03371                 for (i = 0; i < (int) nl->nids; i++)
03372                         (nl->ids)[i] = atol (token());
03373 
03374         }
03375 
03376         return(CIF_F90_NAMELIST);
03377 }
03378 
03379 
03380 static int ascii_f90_object (obj)
03381 struct Cif_f90_object *obj;
03382 {
03383         register char *c;
03384         register long i, attr, storeagid;
03385         struct Cif_dim *dim;
03386 
03387         c = token();
03388         if ((obj->nlen = i = strlen (c)) > 0) {
03389                 obj->name = _Cif_space[lmode] (i+1, lcifd);
03390                 if (obj->name == NULL)
03391                         return (CIF_NOMEM);
03392                 (void) strcpy (obj->name, c);
03393         }
03394         else
03395                 obj->name = NULL;
03396         obj->symid = atol (token());
03397         obj->scopeid = atol (token());
03398 
03399         /*
03400          * Map the compiler generated data type into a new value which
03401          * corresponds where it can with f77 and is non-overlapping for
03402          * other cases that have no direct equivalent; see CIF_[F90_]_DT_?? in cif.h
03403          */
03404         obj->dtype = atoi (token());
03405         if (_Cif_filetbl[lcifd].version < 3) {
03406             if (obj->dtype < CIF_F90_DT_MAX)
03407                 obj->dtype = _Cif_f90_to_f77_dtypes[obj->dtype];
03408             /* else it's a derived type, so leave the number */
03409         }
03410 
03411         obj->symclass = atoi (token());
03412         obj->storage = atol (token());
03413 
03414         c = token();
03415         if (c != (char *) NULL &&
03416             *c != (char) NULL) {
03417             storeagid = atol(c);
03418             if (storeagid < 0)
03419                 obj->storageid = 0;
03420             else
03421                 obj->storageid = storeagid;
03422         }
03423 
03424         c = token();
03425         if (*c != 0 &&
03426             (i = atol (c)) >= 0) {
03427                 obj->valoffset = 1;
03428                 obj->offset = i;
03429         }
03430 
03431 
03432         /* get attributes */
03433         attr = strtol (token(), (char **)NULL, 16);
03434         obj->imptype = ((attr & F90_CO_ATTR_IMPTYPE) != 0);
03435         obj->pointee = ((attr & F90_CO_ATTR_POINTEE) != 0);
03436         obj->deftype = ((attr & F90_CO_ATTR_DEF_TYPE) != 0);
03437         obj->startype = ((attr & F90_CO_ATTR_STAR_TYPE) != 0);
03438         obj->kindtype = ((attr & F90_CO_ATTR_KIND_TYPE) != 0);
03439         obj->save = ((attr & F90_CO_ATTR_SAVE) != 0);
03440         obj->data = ((attr & F90_CO_ATTR_DATA) != 0);
03441         obj->equiv = ((attr & F90_CO_ATTR_EQUIV) != 0);
03442         obj->arraydec = ((attr & F90_CO_ATTR_ARRAY_DEC) != 0);
03443         obj->geomdec = ((attr & F90_CO_ATTR_GEOM_DEC) != 0);
03444         obj->peresident = ((attr & F90_CO_ATTR_PE_RESIDENT) != 0);
03445         obj->allocatable = ((attr & F90_CO_ATTR_ALLOCATABLE) != 0);
03446         obj->intentin = ((attr & F90_CO_ATTR_INTENTIN) != 0);
03447         obj->intentout = ((attr & F90_CO_ATTR_INTENTOUT) != 0);
03448         obj->intentinout = ((attr & F90_CO_ATTR_INTENTINOUT) != 0);
03449         obj->optional = ((attr & F90_CO_ATTR_OPTIONAL) != 0);
03450         obj->pointer = ((attr & F90_CO_ATTR_POINTER) != 0);
03451         obj->priv = ((attr & F90_CO_ATTR_PRIVATE) != 0);
03452         obj->target = ((attr & F90_CO_ATTR_TARGET) != 0);
03453         obj->localname = ((attr & F90_CO_ATTR_LOCAL_NAME) != 0);
03454 
03455         /* we only get a derived type is when this object is a component of structure */
03456 
03457         if (obj->symclass == CIF_F90_SC_STRUCT)
03458           obj->dervid = atol (token());
03459         else
03460           c = token();
03461 
03462         c = token ();
03463         if (*c == 'E')
03464           obj->chartype = CIF_DM_EXPR;
03465         else if (*c == '*')
03466           obj->chartype = CIF_DM_ASSUMED;
03467         else {
03468           obj->chartype = CIF_DM_CONSTANT;
03469           obj->charlen = atol (c);
03470         }
03471 
03472         obj->ndims = atoi (token());
03473 
03474         if (obj->ndims == 0) {
03475           c = token();  /* remove the array type which isn't valid for a non-array (scalar) */
03476         }
03477         else {
03478           obj->atype = atoi(token());
03479           if (obj->atype != CIF_AT_DEFERRED) {  /* deferred arrays have have all dimensions
03480                                                  * assumed as ':', so are not given in the cif
03481                                                  */
03482 
03483             dim = obj->dim = (struct Cif_dim *)_Cif_space[lmode]
03484               (sizeof(struct Cif_dim)*obj->ndims, lcifd);
03485             if (dim == NULL)
03486               return (CIF_NOMEM);
03487             for (i=0; i < (int) obj->ndims; i++) {
03488               c = token ();
03489               if (*c == 'E') {
03490                 dim->ltype = CIF_DM_EXPR;
03491                 dim->lower = 0;
03492               } else if (*c == '*') {
03493                 dim->ltype = CIF_DM_ASSUMED;
03494                 dim->lower = 0;
03495               } else {
03496                 dim->ltype = CIF_DM_CONSTANT;
03497                 dim->lower = atol (c);
03498               }
03499               if (obj->atype == CIF_AT_ASSUMED) {
03500                 dim->utype = CIF_DM_ASSUMED;
03501                 dim->upper = 0;
03502               }
03503               else {
03504                 c = token ();
03505                 if (*c == 'E') {
03506                   dim->utype = CIF_DM_EXPR;
03507                   dim->upper = 0;
03508                 } else if (*c == '*') {
03509                   dim->utype = CIF_DM_ASSUMED;
03510                   dim->upper = 0;
03511                 } else {
03512                   dim->utype = CIF_DM_CONSTANT;
03513                   dim->upper = atol (c);
03514                 }
03515               }
03516               dim++;
03517             }
03518           }
03519       }
03520 
03521         /* read distribution code, arrays only */
03522         c = token();
03523         if (c != (char *) NULL &&
03524             *c != (char) NULL) {
03525             obj->dist = atoi (c);
03526         }
03527 
03528         /* read geometry id, present only for certain array distributions */
03529         c = token();
03530         if (c != (char *) NULL &&
03531             *c != (char) NULL) {
03532             obj->geomid = atol (c);
03533         }
03534 
03535         /* read pointer id, only if this is a CRI pointee */
03536 
03537         c = token();
03538         if (c != (char *) NULL &&
03539             *c != (char) NULL) {
03540             obj->pointerid = atol (c);
03541         }
03542 
03543         return(CIF_F90_OBJECT);
03544 }
03545 
03546 
03547 static int ascii_f90_misc_opts (mo)
03548 struct Cif_f90_misc_opts *mo;
03549 {
03550         register int i;
03551         register char *c;
03552         register int tmp;
03553 
03554         mo->intlen = atoi (token());
03555         mo->msglvl = atoi (token());
03556         mo->vopt = atoi (token());
03557         mo->trunc = atoi (token ());
03558         mo->truncval = atoi (token());
03559         tmp = llist(&(mo->msgno), (int *) NULL);
03560         if (tmp < 0)
03561           return (CIF_NOMEM);
03562         mo->nmsgs = tmp;
03563 
03564         tmp = strlist (&(mo->cdirs));
03565         if (tmp < 0)
03566           return (CIF_NOMEM);
03567         mo->ncdirs = tmp;
03568 
03569         c = token();
03570         if ((mo->onlen = i = strlen (c)) > 0) {
03571                 mo->objname = _Cif_space[lmode] (i+1, lcifd);
03572                 if (mo->objname == NULL)
03573                         return (CIF_NOMEM);
03574                 (void) strcpy (mo->objname, c);
03575         }
03576         c = token();
03577         if ((mo->cnlen = i = strlen (c)) > 0) {
03578                 mo->calname = _Cif_space[lmode] (i+1, lcifd);
03579                 if (mo->calname == NULL)
03580                         return (CIF_NOMEM);
03581                 (void) strcpy (mo->calname, c);
03582         }
03583 
03584         c = token();
03585         if ((mo->inlen = i = strlen (c)) > 0) {
03586                 mo->inname = _Cif_space[lmode] (i+1, lcifd);
03587                 if (mo->inname == NULL)
03588                         return (CIF_NOMEM);
03589                 (void) strcpy (mo->inname, c);
03590         }
03591 
03592         c = token();
03593         if ((mo->ciflen = i = strlen (c)) > 0) {
03594                 mo->cifname = _Cif_space[lmode] (i+1, lcifd);
03595                 if (mo->cifname == NULL)
03596                         return (CIF_NOMEM);
03597                 (void) strcpy (mo->cifname, c);
03598         }
03599 
03600         mo->cifopts = strtol (token(), (char **)NULL, 16);
03601         mo->swidth = atoi (token ());
03602 
03603         tmp = strlist (&(mo->Pdirs));
03604         if (tmp < 0)
03605           return (CIF_NOMEM);
03606         mo->nPdirs = tmp;
03607 
03608         tmp = strlist (&(mo->pdirs));
03609         if (tmp < 0)
03610           return (CIF_NOMEM);
03611         mo->npdirs = tmp;
03612 
03613         c = token();
03614         mo->srcform = (*c == '0' ? 0 : 1);
03615 
03616         /*
03617          * If we are not at a separator, we must be at the end of line,
03618          * which means that there are no more records
03619          */
03620         if (delim == SEPARATOR) {
03621             mo->runtime = strtol (token(), (char **)NULL, 16);
03622         }
03623 
03624         return(CIF_F90_MISC_OPTS);
03625 }
03626 
03627 
03628 static int ascii_f90_opt_opts (opt)
03629 struct Cif_f90_opt_opts *opt;
03630 {
03631         register int i;
03632         struct Cif_f90_level_opts *optlevel;
03633 
03634         opt->values = strtol (token(), (char **)NULL, 16);
03635         opt->noptlevels = atoi (token());
03636         optlevel = opt->lopts = (struct Cif_f90_level_opts *)_Cif_space[lmode]
03637                   (sizeof(struct Cif_f90_level_opts)*opt->noptlevels, lcifd);
03638         if (optlevel== NULL)
03639           return (CIF_NOMEM);
03640         for (i=0; i < (int) opt->noptlevels; i++) {
03641           optlevel->optinlevel = strtol (token(), (char **)NULL, 16);
03642           optlevel->level = atoi (token ());
03643           optlevel++;
03644         }
03645         opt->newdef = 1; /* internal flag set on this version of the cif
03646                           * to allow cifbinread to correctly read both old
03647                           * and new binary formats */
03648 
03649         return(CIF_F90_OPT_OPTS);
03650 }
03651 
03652 
03653 static int ascii_f90_begin_scope (bs)
03654 struct Cif_f90_begin_scope *bs;
03655 {
03656         bs->scopeid = atol (token ());
03657         bs->symid = atol (token ());
03658         bs->fid = atol (token ());
03659         bs->line = atol (token ());
03660         bs->cpos = atol (token ());
03661         bs->stype = atol (token ());
03662         bs->level = atoi (token ());
03663         bs->parentid = atol (token ());
03664 
03665         return(CIF_F90_BEGIN_SCOPE);
03666 }
03667 
03668 
03669 static int ascii_f90_end_scope (es)
03670 struct Cif_f90_end_scope *es;
03671 {
03672         es->scopeid = atol (token ());
03673         es->fid = atol (token ());
03674         es->line = atol (token ());
03675         es->cpos = atol (token ());
03676         es->error = atoi (token ());
03677 
03678         return(CIF_F90_END_SCOPE);
03679 }
03680 
03681 
03682 static int ascii_f90_scope_info (si)
03683 struct Cif_f90_scope_info *si;
03684 {
03685         register long attr;
03686         register int i;
03687 
03688         si->scopeid = atol (token ());
03689 
03690         attr = strtol (token(), (char **)NULL, 16);
03691         si->impnone = ((attr & SC_ATTR_IMPNONE) != 0);
03692         si->doesio = ((attr & SC_ATTR_IO) != 0);
03693         si->hascalls = ((attr & SC_ATTR_CALL) != 0);
03694         si->hascmics = ((attr & SC_ATTR_CMIC) != 0);
03695 
03696         /*
03697          * If we are not at a separator, we must be at the end of line,
03698          * which means that there are no more records
03699          */
03700         if (delim == SEPARATOR) {
03701                 si->numalts = atoi (token ());
03702                 if (si->numalts > 0) {
03703                         si->entryids =
03704                           (long *) _Cif_space[lmode] (sizeof(long)*si->numalts, lcifd);
03705                         if (si->entryids == NULL)
03706                                 return (CIF_NOMEM);
03707                         for (i = 0; i < (int) si->numalts; i++)
03708                           (si->entryids)[i] = atol (token());
03709                       }
03710         }
03711 
03712         return(CIF_F90_SCOPE_INFO);
03713 }
03714 
03715 
03716 static int ascii_f90_use_module (um)
03717 struct Cif_f90_use_module *um;
03718 {
03719         um->modid = atol (token ());
03720         um->modfid = atol (token ());
03721         um->direct = atoi (token ());
03722 
03723         return(CIF_F90_USE_MODULE);
03724 }
03725 
03726 
03727 static int ascii_f90_rename (rn)
03728 struct Cif_f90_rename *rn;
03729 {
03730         register char *c;
03731         register int i;
03732         register int max_id = 5;
03733 
03734         rn->scopeid = atol (token ());
03735         c = token();
03736         if ((rn->nlen = i = strlen (c)) > 0) {
03737                 rn->name = _Cif_space[lmode] (i+1, lcifd);
03738                 if (rn->name == NULL)
03739                         return (CIF_NOMEM);
03740                 (void) strcpy (rn->name, c);
03741         }
03742 
03743         rn->nameid = atol (token ());
03744         rn->modid = atol (token ());
03745 
03746         c = token();
03747         if ((rn->orignlen = i = strlen (c)) > 0) {
03748                 rn->origname = _Cif_space[lmode] (i+1, lcifd);
03749                 if (rn->origname == NULL)
03750                         return (CIF_NOMEM);
03751                 (void) strcpy (rn->origname, c);
03752         }
03753 
03754         rn->origmodid = atol (token ());
03755 
03756         /*
03757          * Assume a max of 5 and increase as necessary; will an object
03758          * ever be renamed more than 5 times ?
03759          */
03760 
03761         rn->localid = (long *) malloc (sizeof(long) * max_id);
03762         i = 0;
03763         while (1) {
03764             c = token();
03765             if (c != (char *) NULL &&
03766                 *c != (char) NULL) {
03767 
03768                 rn->localid[i] = atol (c);
03769                 i++;
03770                 if (i == max_id) {
03771                     max_id+=5;
03772                     rn->localid = (long *) realloc((char *) rn->localid,
03773                                                    sizeof(long) * max_id);   
03774                 }
03775             }
03776             else {
03777                 break;
03778             }
03779         }
03780         rn->nlocalids = i;
03781 
03782         return(CIF_F90_RENAME);
03783 }
03784 
03785 
03786 static int ascii_f90_int_block (ib)
03787 struct Cif_f90_int_block *ib;
03788 {
03789         register char *c;
03790         register int i;
03791 
03792         if (_Cif_filetbl[lcifd].return_version <= 2) {
03793           struct Cif_f90_int_block_2 *ib2 = (struct Cif_f90_int_block_2 *) ib;
03794 
03795           c = token();
03796           if ((ib2->nlen = i = strlen (c)) > 0) {
03797             ib2->name = _Cif_space[lmode] (i+1, lcifd);
03798             if (ib2->name == NULL)
03799                 return (CIF_NOMEM);
03800             (void) strcpy (ib2->name, c);
03801           }
03802 
03803           ib2->intid = atol (token ());
03804           ib2->scopeid = atol (token());
03805           ib2->type = atoi (token ());
03806 
03807           /*
03808            * this next field could be a set of attributes, but for now it's
03809            * only possible value is 1 for PRIVATE
03810            */
03811 
03812           ib2->priv = (*token() == '1');
03813 
03814           if ((ib2->numints = atoi (token())) > 0) {
03815             ib2->procids = (long *) _Cif_space[lmode] (sizeof(long)*ib2->numints, lcifd);
03816             if (ib2->procids == NULL)
03817                 return (CIF_NOMEM);
03818             for (i = 0; i < (int) ib2->numints; i++)
03819                 (ib2->procids)[i] = atol (token());
03820 
03821           }
03822         }
03823         else {  /* version 3 CIF record, as above + add the moduleid field */
03824 
03825           c = token();
03826           if ((ib->nlen = i = strlen (c)) > 0) {
03827             ib->name = _Cif_space[lmode] (i+1, lcifd);
03828             if (ib->name == NULL)
03829                 return (CIF_NOMEM);
03830             (void) strcpy (ib->name, c);
03831           }
03832 
03833           ib->intid = atol (token ());
03834           ib->scopeid = atol (token());
03835           ib->type = atoi (token ());
03836 
03837           /*
03838            * this next field could be a set of attributes, but for now it's
03839            * only possible value is 1 for PRIVATE
03840            */
03841 
03842           ib->priv = (*token() == '1');
03843 
03844           if ((ib->numints = atoi (token())) > 0) {
03845             ib->procids = (long *) _Cif_space[lmode] (sizeof(long)*ib->numints, lcifd);
03846             if (ib->procids == NULL)
03847                 return (CIF_NOMEM);
03848             for (i = 0; i < (int) ib->numints; i++)
03849                 (ib->procids)[i] = atol (token());
03850           }
03851 
03852           /* moduleid's are only present in V3 CIF's */
03853           if (_Cif_filetbl[lcifd].version >= 3 &&
03854               delim == SEPARATOR) {
03855             ib->moduleid = atol (token());
03856           }
03857         }
03858 
03859         return(CIF_F90_INT_BLOCK);
03860 }
03861 
03862 
03863 static int ascii_f90_vectorization (vect)
03864 struct Cif_f90_vectorization *vect;
03865 {
03866     (void) fprintf(stderr, "libcif: vectorization message %p\n", vect);
03867     return(CIF_F90_VECTORIZATION);
03868 }
03869 #endif /* ndef CRAY2 */
03870 
03871 
03872 
03873 
03874 
03875 static int ascii_unit (unit)
03876 struct Cif_unit *unit;
03877 {
03878         register int i;
03879         register char *c;
03880 
03881         c = token();
03882         unit->nlen = i = strlen (c);
03883         unit->name = _Cif_space[lmode] (i+1, lcifd);
03884         if (unit->name == NULL)
03885                 return (CIF_NOMEM);
03886         (void) strcpy (unit->name, c);
03887         unit->fid = atol (token());
03888         unit->line = atol (token());
03889         unit->cpos = atol (token());
03890         return (CIF_UNIT);
03891 
03892 }
03893 
03894 static int ascii_endunit (eu)
03895 struct Cif_endunit *eu;
03896 {
03897         register int i;
03898         register char *c;
03899 
03900         c = token();
03901         eu->nlen = i = strlen (c);
03902         eu->name = _Cif_space[lmode] (i+1, lcifd);
03903         if (eu->name == NULL)
03904                 return (CIF_NOMEM);
03905         (void) strcpy (eu->name, c);
03906         eu->fid = atol (token());
03907         eu->line = atol (token());
03908         eu->cpos = atol (token());
03909         return (CIF_ENDUNIT);
03910 
03911 }
03912 
03913 static int ascii_usage (usage)
03914 struct Cif_usage *usage;
03915 {
03916 #       define UBINCR 5                 /* use buffer increment value */
03917 
03918         register char *c;
03919         long i, nuses, note_pos = -10; /* a file position, note 0 and -1 have meaning, so
03920                                         * -10 is used to be 'undefined'
03921                                         */
03922 
03923         long utype;
03924 
03925         static struct Cif_use *ubuff = NULL;    /* pointer to base of use buffer */
03926         static int ubi;                         /* index to next slot in ubuff */
03927         static int ubsize = 0;                  /* current max size of ubuff */
03928 
03929 
03930         /*
03931          * If the user wants a v1 cif, then we need to use a different data
03932          * structure
03933          */
03934 
03935         if (_Cif_filetbl[lcifd].return_version == 1) {
03936           struct Cif_usage_1 *usage1 = (struct Cif_usage_1 *) usage;
03937 
03938           usage1->symid = atol (token());
03939           ubi = 0;
03940 
03941           while (1) {
03942 
03943             /* count up number of uses in record */
03944 
03945             i = 0;
03946             c = ntoken;
03947             while (*c != '\0')
03948               if (*c++ == SEPARATOR) i++;
03949             nuses = (++i) / 4;
03950 
03951             /* if not enough space in use buffer, make buffer bigger */
03952 
03953             if (ubi + nuses > ubsize) {
03954               if (ubsize == 0) {
03955                 ubsize = UBINCR;
03956 
03957                 ubuff = (struct Cif_use *) malloc (sizeof(struct Cif_use)*UBINCR);
03958               }
03959               else {
03960                 ubsize += UBINCR;
03961                 ubuff = (struct Cif_use *)realloc (ubuff,
03962                                                    sizeof(struct Cif_use)*ubsize);
03963               }
03964               if (ubuff == NULL)
03965                 return (CIF_NOMEM);
03966             }
03967             for (i = 0; i < nuses; i++) {
03968               ubuff[ubi].fid = atol (token());
03969               ubuff[ubi].line = atol (token());
03970               ubuff[ubi].cpos = atol (token());
03971 
03972               /*
03973                * Fortran and C usage values have different meanings
03974                * In C, values are in hex and bit significant;
03975                * Fortran is decimal and different nummeric values
03976                * represent different usages with no bit significance
03977                */
03978 
03979               if (_Cif_filetbl[lcifd].lang == CIF_LG_C ||
03980                   _Cif_filetbl[lcifd].lang == CIF_LG_CC) {
03981                 ubuff[ubi].utype =
03982                   strtol (token(), (char **)NULL, 16);
03983               }
03984               else {
03985                 utype = atol (token());
03986                 ubuff[ubi].utype = utype % 100;
03987                 /*
03988                  * in a v2 cif, a usage type > 100 indicates that the object
03989                  * is used in a data statement
03990                  */
03991                 if (_Cif_filetbl[lcifd].return_version != 1) {
03992                     if (_Cif_filetbl[lcifd].return_version != 1) {
03993                         if (utype >= 200)
03994                             ubuff[ubi].init = 1;
03995                         else
03996                             if (utype >= 100)
03997                                 ubuff[ubi].data = 1;
03998                     }
03999                 }
04000               }
04001               ubi++;
04002             }
04003 
04004             /*
04005              * Read next record.  If usage and same object, go back and add to
04006              * current list.  Otherwise, mark that buffer contains record and go on.
04007              */
04008 
04009             /*
04010              * note where we are now so that if the next record is not
04011              * a usage we can position the curent pos at it correctly
04012              */
04013 
04014             note_pos = Cif_Getpos(lcifd);
04015 
04016             if (fgets (_Cif_filetbl[lcifd].ip, CIF_BUFSIZE, _Cif_filetbl[lcifd].fd)
04017                 == NULL)
04018               {
04019                 if (feof(_Cif_filetbl[lcifd].fd))
04020                   break;
04021                 else
04022                   return (CIF_SYSERR);
04023               }
04024             ntoken = _Cif_filetbl[lcifd].ip;
04025             if (atoi (token ()) != CIF_USAGE) {
04026               _Cif_filetbl[lcifd].ifull = YES;
04027               break;
04028             }
04029             else if (atol (token ()) != usage1->symid) {
04030               _Cif_filetbl[lcifd].ifull = YES;
04031               break;
04032             }
04033           }
04034 
04035           /* Make sure that the file position is correct before we continue */
04036 
04037           if (note_pos != -10)
04038               (void) Cif_Setpos(lcifd, note_pos);
04039 
04040           /* Sort the usages, allocate a new buffer, and copy them over */
04041 
04042           if (ubi > 1)
04043               (void) qsort ( (char *)ubuff, ubi, sizeof(struct Cif_use), (int(*)()) compuse);
04044           i = sizeof(struct Cif_use) * ubi;
04045           usage1->use = (struct Cif_use *)_Cif_space[lmode] (i, lcifd);
04046           if (usage1->use == NULL)
04047             return (CIF_NOMEM);
04048           (void) memcpy ((char *)usage1->use, (char *)ubuff, i);
04049           usage1->nuses = ubi;
04050         }
04051 
04052         else  { /* returning a v2 cif */
04053 
04054           usage->symid = atol (token());
04055           ubi = 0;
04056 
04057           while (1) {
04058 
04059             /* count up number of uses in record */
04060 
04061             i = 0;
04062             c = ntoken;
04063             while (*c != '\0')
04064               if (*c++ == SEPARATOR) i++;
04065             nuses = (++i) / 4;
04066 
04067             /* if not enough space in use buffer, make buffer bigger */
04068 
04069             if (ubi + nuses > ubsize) {
04070               if (ubsize == 0) {
04071                 ubsize = UBINCR;
04072                 ubuff = (struct Cif_use *) malloc (sizeof(struct Cif_use)*UBINCR);
04073                 }
04074               else {
04075                 ubsize += UBINCR;
04076                 ubuff = (struct Cif_use *)realloc (ubuff,
04077                                                    sizeof(struct Cif_use)*ubsize);
04078               }
04079               if (ubuff == NULL)
04080                 return (CIF_NOMEM);
04081             }
04082             for (i = 0; i < nuses; i++) {
04083               (void) memset((char *)&ubuff[ubi], 0, sizeof(struct Cif_use));
04084               ubuff[ubi].fid = atol (token());
04085               ubuff[ubi].line = atol (token());
04086               ubuff[ubi].cpos = atol (token());
04087 
04088               /* Fortran and C usage values have different meanings
04089                * In C, values are in hex and bit significant;
04090                * Fortran is decimal and different nummeric values
04091                * represent different usages with no bit significance
04092                */
04093 
04094               if (_Cif_filetbl[lcifd].lang == CIF_LG_C ||
04095                   _Cif_filetbl[lcifd].lang == CIF_LG_CC) {
04096                 ubuff[ubi].utype =
04097                   strtol (token(), (char **)NULL, 16);
04098               }
04099               else {
04100                   utype = atol (token());
04101                   ubuff[ubi].utype = utype % 100;
04102                   /*
04103                    * in a v2 cif, a usage type > 100 indicates that the object
04104                    * is used in a data statement
04105                    */
04106                   if (_Cif_filetbl[lcifd].return_version != 1) {
04107                       if (_Cif_filetbl[lcifd].return_version != 1) {
04108                           if (utype >= 200)
04109                               ubuff[ubi].init = 1;
04110                           else
04111                               if (utype >= 100)
04112                                   ubuff[ubi].data = 1;
04113                       }
04114                   }
04115               }
04116               ubi++;
04117           }
04118 
04119             /*
04120              * Read next record.  If usage and same object, go back and add to
04121              * current list.  Otherwise, mark that buffer contains record and go on.
04122              */
04123 
04124             /*
04125              * note where we are now so that if the next record is not
04126              * a usage we can position the curent pos at it correctly
04127              */
04128 
04129             note_pos = Cif_Getpos(lcifd);
04130 
04131             if (fgets (_Cif_filetbl[lcifd].ip, CIF_BUFSIZE, _Cif_filetbl[lcifd].fd)
04132                 == NULL)
04133               {
04134                 if (feof(_Cif_filetbl[lcifd].fd))
04135                   break;
04136                 else
04137                   return (CIF_SYSERR);
04138               }
04139             ntoken = _Cif_filetbl[lcifd].ip;
04140             if (atoi (token ()) != CIF_USAGE) {
04141               _Cif_filetbl[lcifd].ifull = YES;
04142               break;
04143             }
04144             else if (atol (token ()) != usage->symid) {
04145               _Cif_filetbl[lcifd].ifull = YES;
04146               break;
04147             }
04148           }
04149 
04150           /* Make sure that the file position is correct before we continue */
04151 
04152           if (note_pos != -10)
04153               (void) Cif_Setpos(lcifd, note_pos);
04154 
04155           /* Sort the usages, allocate a new buffer, and copy them over */
04156 
04157           if (ubi > 1)
04158               (void) qsort ( (char *)ubuff, ubi, sizeof(struct Cif_use), (int(*)()) compuse);
04159           i = sizeof(struct Cif_use) * ubi;
04160           usage->use = (struct Cif_use *)_Cif_space[lmode] (i, lcifd);
04161           if (usage->use == NULL)
04162             return (CIF_NOMEM);
04163           (void) memcpy ((char *)usage->use, (char *)ubuff, i);
04164           usage->nuses = ubi;
04165 
04166       }
04167 
04168         return (CIF_USAGE);
04169 
04170 }
04171 
04172 
04173 /*
04174  * cif_usage changed slightly for f90 in that only one usage will
04175  * be created per record and that there is an optional new last field
04176  * which describes the member symbol id's; that is if a%b%c is referenced,
04177  * a will be given as the usual symbol id, b and c will be the member symbol
04178  * id's. As such it is easier to parse these separately.
04179  */
04180 
04181 static int ascii_f90_usage (usage)
04182 struct Cif_usage *usage;
04183 {
04184         long i;
04185         long utype;
04186 
04187         static struct Cif_use *ubuff = NULL;    /* pointer to base of use buffer */
04188 
04189         usage->symid = atol (token());
04190 
04191         ubuff = (struct Cif_use *) _Cif_space[lmode] (sizeof(struct Cif_use),
04192                                                       lcifd);
04193         ubuff->fid = atol (token());
04194         ubuff->line = atol (token());
04195         ubuff->cpos = atol (token());
04196         utype = atol(token());
04197         ubuff->utype = utype % 100;
04198         /*
04199          * in a v2 cif, a usage type > 100 indicates that the object
04200          * is used in a data statement
04201          */
04202         ubuff->init = 0;
04203         ubuff->data = 0;
04204         if (_Cif_filetbl[lcifd].return_version != 1) {
04205             if (utype >= 200)
04206                 ubuff->init = 1;
04207             else
04208                 if (utype >= 100)
04209                     ubuff->data = 1;
04210         }
04211 
04212         /*
04213          * Now see if there are any extra symol id's which will represent the
04214          * parent symbol id's (see comment at head of this function)
04215          */
04216 
04217         /* There are still things to read if we are just at a delimiter */
04218 
04219         if (delim == SEPARATOR) {
04220           usage->nmembs = atoi (token());
04221           if (usage->nmembs > 0) {
04222             usage->membs = (long *) _Cif_space[lmode] ((sizeof(long) * usage->nmembs),
04223                                                        lcifd);
04224             for (i = 0; i < (int) usage->nmembs; i++) {
04225               usage->membs[i] = atol (token());
04226             }
04227           }
04228         }
04229 
04230         usage->use = ubuff;
04231         usage->nuses = 1;
04232 
04233         return (CIF_USAGE);
04234 
04235 }
04236 
04237 
04238 #ifndef CRAY2
04239 static int ascii_BE_node (ent)
04240 struct Cif_BE_node *ent;
04241 {
04242         char *cp;
04243         int i, n;
04244 
04245         if ( _Cif_filetbl[lcifd].return_version == 2 ) {
04246 
04247             struct Cif_BE_node_2 *v2 = (struct Cif_BE_node_2 *) ent;
04248             v2->block = atoi (token());
04249             v2->blocklet = atoi (token());
04250             v2->is_entry = atoi (token());
04251             v2->nsuccs = n = atoi (token());
04252             if ( n < 0 ) {
04253                 return( CIF_BADFORM );
04254             } else if ( n == 0 ) {
04255                 v2->succs = (int *) NULL;
04256             } else {
04257                 v2->succs = (int *) 
04258                     _Cif_space[ lmode ](n * sizeof( int ), lcifd);
04259                 if ( v2->succs == NULL )
04260                     return( CIF_NOMEM );
04261                 for ( i = 0; i < n; i++ ) {
04262                     v2->succs[ i ] = atoi (token());
04263                 }
04264             }
04265             v2->nlines = n = atoi (token());
04266             if ( n < 0 ) {
04267                 return( CIF_BADFORM );
04268             } else if ( n == 0 ) {
04269                 v2->lines = (int *) NULL;
04270             } else {
04271                 if ( _Cif_filetbl[lcifd].version >= 3 ) {
04272                     /* user wants V2 record, but this is V3
04273                      * so read up fids and toss them */
04274                     for ( i = 0; i < n; i++ ) {
04275                         (void) token();
04276                     }
04277                 }
04278                 v2->lines = (int *) 
04279                     _Cif_space[ lmode ](n * sizeof( int ), lcifd);
04280                 if ( v2->lines == NULL )
04281                     return( CIF_NOMEM );
04282                 for ( i = 0; i < n; i++ ) {
04283                     v2->lines[ i ] = atoi (token());
04284                 }
04285             }
04286             v2->type = atoi (token());
04287             v2->subtype = atoi (token());
04288             v2->index = atoi (token());
04289             cp = token();
04290             n = strlen (cp);
04291             v2->label = _Cif_space[ lmode ](n+1, lcifd);
04292             if ( v2->label == NULL )
04293                 return( CIF_NOMEM );
04294             (void) strcpy( v2->label, cp );
04295             for ( i = 0; i < CIF_IT_MAX; i++ ) {
04296                 v2->icnt[ i ] = atoi (token());
04297             }
04298             v2->app_before = atoi (token());
04299             v2->app_after = atoi (token());
04300             v2->clocks = atoi (token());
04301 
04302         } else {                /* user wants a V3 format record */
04303 
04304             ent->block = atoi (token());
04305             ent->blocklet = atoi (token());
04306             ent->is_entry = atoi (token());
04307             ent->nsuccs = n = atoi (token());
04308             if ( n < 0 ) {
04309                 return( CIF_BADFORM );
04310             } else if ( n == 0 ) {
04311                 ent->succs = (int *) NULL;
04312             } else {
04313                 ent->succs = (int *) 
04314                     _Cif_space[ lmode ](n * sizeof( int ), lcifd);
04315                 if ( ent->succs == NULL )
04316                     return( CIF_NOMEM );
04317                 for ( i = 0; i < n; i++ ) {
04318                     ent->succs[ i ] = atoi (token());
04319                 }
04320             }
04321             ent->nlines = n = atoi (token());
04322             if ( n < 0 ) {
04323                 return( CIF_BADFORM );
04324             } else if ( n == 0 ) {
04325                 ent->fid = (int *) NULL;
04326                 ent->lines = (int *) NULL;
04327             } else {
04328                 ent->fid = (int *) 
04329                     _Cif_space[ lmode ](n * sizeof( int ), lcifd);
04330                 if ( ent->fid == NULL )
04331                     return( CIF_NOMEM );
04332                 ent->lines = (int *) 
04333                     _Cif_space[ lmode ](n * sizeof( int ), lcifd);
04334                 if ( ent->lines == NULL )
04335                     return( CIF_NOMEM );
04336                 if ( _Cif_filetbl[lcifd].version >= 3 ) {
04337                     for ( i = 0; i < n; i++ ) {
04338                         ent->fid[ i ] = atoi (token());
04339                     }
04340                     for ( i = 0; i < n; i++ ) {
04341                         ent->lines[ i ] = atoi (token());
04342                     }
04343                 } else {
04344                     for ( i = 0; i < n; i++ ) {
04345                         ent->fid[ i ] = 0;
04346                         ent->lines[ i ] = atoi (token());
04347                     }
04348                 }
04349             }
04350             ent->type = atoi (token());
04351             ent->subtype = atoi (token());
04352             ent->index = atoi (token());
04353             cp = token();
04354             n = strlen (cp);
04355             ent->label = _Cif_space[ lmode ](n+1, lcifd);
04356             if ( ent->label == NULL )
04357                 return( CIF_NOMEM );
04358             (void) strcpy( ent->label, cp );
04359             for ( i = 0; i < CIF_IT_MAX; i++ ) {
04360                 ent->icnt[ i ] = atoi (token());
04361             }
04362             ent->app_before = atoi (token());
04363             ent->app_after = atoi (token());
04364             ent->clocks = atoi (token());
04365             if ( *ntoken != 0 )
04366                 return( CIF_BADFORM );
04367         }
04368         return( CIF_BE_NODE );
04369 }
04370 
04371 
04372 static int ascii_BE_fid (ent)
04373 struct Cif_BE_fid *ent;
04374 {
04375         char *cp;
04376         int i, n;
04377 
04378         ent->block = atoi (token());
04379         ent->blocklet = atoi (token());
04380 
04381         ent->nfid = n = atoi (token());
04382         if ( n < 0 ) {
04383             return( CIF_BADFORM );
04384         } else if ( n == 0 ) {
04385             ent->fid = (int *) NULL;
04386         } else {
04387             ent->fid = (int *) 
04388                 _Cif_space[ lmode ](n * sizeof( int ), lcifd);
04389             if ( ent->fid == NULL )
04390                 return( CIF_NOMEM );
04391             for ( i = 0; i < n; i++ ) {
04392                 ent->fid[ i ] = atoi (token());
04393             }
04394         }
04395         return( CIF_BE_FID );
04396 }
04397 #endif /* CRAY2 */
04398 
04399 
04400 static int ascii_cc_type (spos)
04401 struct Cif_cc_type *spos;
04402 {
04403     int i, n;
04404     char *c;
04405 
04406     spos->scopeid = atoi(token());
04407     spos->ptype = atol(token());
04408     spos->size = atol(token());
04409     spos->typeId = atol(token());
04410     spos->type = atoi(token());
04411 
04412     switch( spos->type ) {
04413     case CIF_CCT_INT:
04414         spos->flags = atoi(token());
04415         spos->prec = atoi(token());
04416         break;
04417     case CIF_CCT_FLOAT:
04418         spos->subtype = atoi(token());
04419         break;
04420     case CIF_CCT_COMPLEX:
04421         spos->subtype = atoi(token());
04422         break;
04423     case CIF_CCT_CLASS:
04424     case CIF_CCT_STRUCT:
04425     case CIF_CCT_UNION:
04426     case CIF_CCT_ENUM:
04427         c = token();
04428         spos->nlen = i = strlen (c);
04429         spos->name = _Cif_space[lmode] (i+1, lcifd);
04430         if (spos->name == NULL)
04431             return (CIF_NOMEM);
04432         (void) strcpy (spos->name, c);
04433         spos->symid = atoi(token());
04434         spos->nmem = i = atoi(token());
04435         i *= sizeof( int );
04436         spos->mem = (int *)_Cif_space[lmode] (i, lcifd);
04437         if (spos->mem == NULL)
04438             return (CIF_NOMEM);
04439         for ( i = 0; i < (int)spos->nmem; i++ )
04440             spos->mem[ i ] = atoi(token());
04441         break;
04442