Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
cifrecgroup.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/cifrecgroup.c        30.5    06/27/97 14:34:02";
00038 
00039 
00040 /*
00041  *      Cif_Recgroup retrieves all the records of a particular type that belong
00042  *      to a single unit.
00043  */
00044 
00045 #define CIF_VERSION 3
00046 
00047 #ifdef _ABSOFT
00048 #include "cif.h"
00049 #else
00050 #include <cif.h>
00051 #endif
00052 
00053 #include <memory.h>
00054 #include <stdio.h>
00055 #include <stdlib.h>
00056 
00057 #include "cif_int.h"
00058 
00059 int
00060 Cif_Recgroup
00061 #ifdef __STDC__
00062 (int cifd, struct Cif_unitdir *udir, int rtype, struct Cif_generic **rptr)
00063 #else
00064 (cifd, udir, rtype, rptr)
00065 int cifd;
00066 struct Cif_unitdir *udir;
00067 int rtype;
00068 struct Cif_generic **rptr;
00069 #endif
00070 {
00071 
00072         register int i, mode, n;
00073         struct Cif_urectbl *urp;
00074         struct Cif_generic *cr;
00075         struct Cif_generic *tmp_rec;
00076         FILE *fd;
00077         struct Cif_filedir *fdir;
00078         int status;
00079         int nrecords;
00080         long pos;
00081 
00082         if (cifd < 0 || cifd > CIF_FT_SIZE || _Cif_filetbl[cifd].form == NOT_A_CIF)
00083                 return (CIF_NOTOPEN);
00084         else if (_Cif_filetbl[cifd].optype == 'w' ||
00085                  _Cif_filetbl[cifd].form == ASCII_CIF ||
00086                  _Cif_filetbl[cifd].seek == NO ||
00087                  rtype < 0 ||
00088                  rtype > ((_Cif_filetbl[cifd].return_version == 1) ?
00089                                 CIF_MAXRECORD_1 : CIF_MAXRECORD) ||
00090                  _Cif_structsize[rtype][_Cif_filetbl[cifd].return_version] == 0)
00091                 return (CIF_BADREQ);
00092 
00093         /* Position file to start of record group and read in as many records
00094          * as are present.
00095          */
00096 
00097         fd = _Cif_filetbl[cifd].fd;
00098 
00099         /* if udir == NULL, we don't want to use the unit dir record, but want to
00100            read records global to the file */
00101 
00102         if (udir == (struct Cif_unitdir *) NULL) {
00103 
00104                 /*
00105                  * If memory management mode isn't set, then set to FIXED.  If the mode is
00106                  * FIXED, reset the amount of buffer used.
00107                  */
00108 
00109                 mode = _Cif_filetbl[cifd].mode;
00110                 if (mode == CIF_MEM_DEFAULT) {
00111                         if ((status = Cif_Memmode (cifd, CIF_MEM_FIXED)) != 0)
00112                                 return (status);
00113                         mode = _Cif_filetbl[cifd].mode;
00114                       }
00115                 if (mode == CIF_MEM_FIXED)
00116                         _Cif_memarea[_Cif_filetbl[cifd].fme].mused = 0;
00117 
00118 
00119                 switch (rtype) {
00120 
00121                 case CIF_CIFHDR : {
00122 
00123                   /* start from the beginning of the file, first record is the cif_cifhdr */
00124 
00125                     (void) Cif_Setpos(cifd, CIF_FIRST_RECORD);
00126                   
00127                   status =  Cif_Getrecord(cifd, rptr);
00128                   if (status < 0)
00129                     return(status);
00130                   else
00131                     return(1);  /* one record returned */
00132 
00133                 }
00134 
00135                 case CIF_FILEDIR : {
00136                   status =  Cif_Getfiledir(cifd, (struct Cif_filedir **) rptr);
00137                   if (status < 0)
00138                     return(status);
00139                   else
00140                     return(1);  /* one record returned */
00141 
00142                 }
00143 
00144                 case CIF_SRCFILE : {
00145 
00146                   /* source file comes after the filedir */
00147 
00148                   status =  Cif_Getfiledir(cifd, &fdir);
00149                   if (status < 0)
00150                     return(status);
00151 
00152                   status =  Cif_Getrecord(cifd, rptr);
00153                   if (status < 0)
00154                     return(status);
00155                   else
00156                     return(1);  /* one record returned */
00157                 }
00158 
00159                 case CIF_FILE : {
00160 
00161                   /* find out how many files there will be from the filedir */
00162 
00163                   status =  Cif_Getfiledir(cifd, &fdir);
00164                   if (status < 0)
00165                     return(status);
00166 
00167                   nrecords = CIFFDIR(fdir)->nfiles;
00168 
00169                   if (nrecords > 0) {
00170                         n = nrecords *
00171                           _Cif_structsize[rtype][_Cif_filetbl[cifd].return_version];
00172 
00173                         cr = *rptr = (struct Cif_generic *) _Cif_space[mode] (n, cifd);
00174                         if (cr == NULL)
00175                                 return (CIF_NOMEM);
00176                         (void) memset ((char *)cr, '\0', n);
00177 
00178                         do {  /* look for first CIF_FILE */
00179                           pos = Cif_Getpos(cifd);  /* note start of record postion */
00180 
00181                           if ((status = Cif_Getrecord(cifd, &tmp_rec)) < 0)
00182                             return(status);
00183 
00184                         } while (status != CIF_FILE);
00185 
00186                         (void) Cif_Setpos(cifd, pos); /* go back to where the required records
00187                                                   started */
00188 
00189                         for (i = 0; i < nrecords; i++) {
00190                                 if (fread ((char *)cr,
00191                                            _Cif_shortsize[rtype][_Cif_filetbl[cifd].version],
00192                                            1, fd) != 1) IO_ERROR;
00193 
00194                                 if ((n = _Cif_binread (cifd, rtype, cr, fd)) < 0)
00195                                         return (n);
00196                                 cr = (struct Cif_generic *)((char *)cr +
00197                                         _Cif_structsize[rtype][_Cif_filetbl[cifd].return_version]);
00198 
00199                               }
00200                       }
00201 
00202                   return(nrecords);
00203                 }
00204 
00205                 case CIF_INCLUDE : {
00206 
00207                   /* find out how many files there will be from the filedir */
00208 
00209                   status =  Cif_Getfiledir(cifd, &fdir);
00210                   if (status < 0)
00211                     return(status);
00212 
00213                   nrecords = CIFFDIR(fdir)->nincs;
00214 
00215                   if (nrecords > 0) {
00216                         n = nrecords *
00217                           _Cif_structsize[rtype][_Cif_filetbl[cifd].return_version];
00218 
00219                         cr = *rptr = (struct Cif_generic *) _Cif_space[mode] (n, cifd);
00220                         if (cr == NULL)
00221                                 return (CIF_NOMEM);
00222                         (void) memset ((char *)cr, '\0', n);
00223 
00224                         do {  /* look for first CIF_INCLUDE */
00225                           pos = Cif_Getpos(cifd);  /* note start of record postion */
00226 
00227                           if ((status = Cif_Getrecord(cifd, &tmp_rec)) < 0)
00228                             return(status);
00229 
00230                         } while (status != CIF_INCLUDE &&
00231                                  status != CIF_UNIT);
00232 
00233                         (void) Cif_Setpos(cifd, pos); /* go back to where the required records
00234                                                   started */
00235 
00236                         for (i = 0; i < nrecords; i++) {
00237                                 if (fread ((char *)cr,
00238                                            _Cif_shortsize[rtype][_Cif_filetbl[cifd].version],
00239                                            1, fd) != 1) IO_ERROR;
00240 
00241                                 if ((n = _Cif_binread (cifd, rtype, cr, fd)) < 0)
00242                                         return (n);
00243                                 cr = (struct Cif_generic *)((char *)cr +
00244                                         _Cif_structsize[rtype][_Cif_filetbl[cifd].return_version]);
00245 
00246                               }
00247                       }
00248 
00249                   return(nrecords);
00250                 }
00251 
00252                 case CIF_UNITDIR : {
00253 
00254                   status =  Cif_Getfiledir(cifd, &fdir);
00255                   if (status < 0)
00256                     return(status);
00257 
00258                   status = Cif_Getunitdir(cifd, fdir->ut, (struct Cif_unitdir **) rptr );
00259                   if (status < 0)
00260                         return(status);
00261                   else
00262                     return(1);  /* unitdir returned */
00263                 }
00264 
00265                 case CIF_SRC_POS:
00266                 case CIF_MESSAGE : {
00267 
00268                     /* start from the beginning of the file and read all of
00269                      * the cif_messages, until we hit the first unit record
00270                      */
00271                     (void) Cif_Setpos(cifd, CIF_FIRST_RECORD);
00272 
00273                     do {  /* look for first record */
00274                         pos = Cif_Getpos(cifd);  /* note start of record postion */
00275                         if ((status = Cif_Getrecord(cifd, &tmp_rec)) < 0)
00276                             return(status);
00277                     } while (status != rtype &&
00278                              status != CIF_UNIT);
00279 
00280                     if (status != rtype) {
00281                         return(0);  /* record was not found */
00282                     }
00283 
00284                     (void) Cif_Setpos(cifd, pos); /* go back to where the required records
00285                                                      started */
00286                     nrecords = -1;
00287                     do {  /* Count the messages */
00288 /*                      pos = Cif_Getpos(cifd);   note start of record postion */
00289                         if ((status = Cif_Getrecord(cifd, &tmp_rec)) < 0)
00290                             return(status);
00291 
00292                         nrecords++;
00293 
00294                     } while (status == rtype);
00295 
00296                     /* Allocate memory for the messages */
00297 
00298                     if (nrecords > 0) {
00299                         n = nrecords *
00300                             _Cif_structsize[rtype][_Cif_filetbl[cifd].return_version];
00301 
00302                         cr = *rptr = (struct Cif_generic *) _Cif_space[mode] (n, cifd);
00303                         if (cr == NULL)
00304                             return (CIF_NOMEM);
00305                         (void) memset ((char *)cr, '\0', n);
00306 
00307                         (void) Cif_Setpos(cifd, pos); /* go back to where the required records
00308                                                          started */
00309 
00310                         for (i = 0; i < nrecords; i++) {
00311                             if (fread ((char *)cr,
00312                                        _Cif_shortsize[rtype][_Cif_filetbl[cifd].version],
00313                                        1, fd) != 1) IO_ERROR;
00314 
00315                             if ((n = _Cif_binread (cifd, rtype, cr, fd)) < 0)
00316                                 return (n);
00317                             cr = (struct Cif_generic *)((char *)cr +
00318                                                         _Cif_structsize[rtype][_Cif_filetbl[cifd].return_version]);
00319 
00320                         }
00321                     }
00322 
00323                     return(nrecords);
00324                 }
00325 
00326 
00327                 case CIF_MACH_CHAR :
00328                 case CIF_ND_MSG :
00329                 case CIF_EDOPTS :
00330                 case CIF_MISC_OPTS :
00331                 case CIF_OPT_OPTS: {
00332                   /* start from the beginning of the file, first record is the cif_cifhdr */
00333 
00334                     (void) Cif_Setpos(cifd, CIF_FIRST_RECORD);
00335 
00336                   do {
00337                     status =  Cif_Getrecord(cifd, rptr);
00338 
00339                   }
00340                   while (status != rtype && status > 0);
00341 
00342                   if (status == rtype)
00343                     return(1);  /* record was found */
00344                   else
00345                     if (status != CIF_EOF)
00346                       return(status);  /* something went wrong */
00347                     else
00348                       return(0);  /* record was not found */
00349 
00350                 }
00351 
00352                 default:
00353                   return (CIF_BADREQ);  /* all other records should be accessed via
00354                                            the unitrecord */
00355                 }
00356 
00357 
00358 
00359         }
00360 
00361 
00362         else {  /* read from the unitdir to find out how many records there are,
00363                    and where they begin */
00364 
00365                 mode = _Cif_filetbl[cifd].mode;  /* note. we don't have to check the mode
00366                                                     to see if it is the default mode as
00367                                                     to get here we must have issued at least
00368                                                     one getrecord to get the unitdir, which
00369                                                     would have checked the mode for us */
00370                 urp = udir->ur;
00371                 if ((nrecords = urp[rtype].nrecords) > 0) {
00372                         if (fseek (fd, (long)urp[rtype].recpos, 0)) return (CIF_SYSERR);
00373 
00374                         /* obtain sufficient storage for the records to be
00375                            returned, which may be different from what we are about
00376                            to read from the disk */
00377 
00378                         n = /* urp[rtype]. */ nrecords *
00379                           _Cif_structsize[rtype][_Cif_filetbl[cifd].return_version];
00380 
00381                         cr = *rptr = (struct Cif_generic *) _Cif_space[mode] (n, cifd);
00382 
00383                         if (cr == NULL)
00384                                 return (CIF_NOMEM);
00385                         (void) memset ((char *)cr, '\0', n);
00386 
00387                         /* cif version being read is the same as that to be returned */
00388 
00389                         if (_Cif_filetbl[cifd].version ==
00390                             _Cif_filetbl[cifd].return_version) {
00391 
00392                           for (i = 0; i < /* urp[rtype]. */ nrecords; i++) {
00393 
00394                                 if (fread ((char *)cr,
00395                                            _Cif_shortsize[rtype][_Cif_filetbl[cifd].version],
00396                                            1, fd) != 1) IO_ERROR;
00397 
00398                                 if ((n = _Cif_binread (cifd, rtype, cr, fd)) < 0)
00399                                         return (n);
00400                                 cr = (struct Cif_generic *)((char *)cr +
00401                                         _Cif_structsize[rtype][_Cif_filetbl[cifd].version]);
00402                               }
00403                         }
00404                         else {
00405                           /* cif version on disk is different to that requested, which means
00406                              that we have to map the binary records accordingly, v1 <-> v2 */
00407 
00408                           /* create a temporary, static buffer in which to read data into
00409                              just in case the cif on disk is larger than the cif record
00410                              to be returned (eg cif v2 on disk; application wants a v1) */
00411 
00412                           if (_cif_map_buffer == (struct Cif_generic *) NULL)
00413                             _cif_map_buffer = (struct Cif_generic *) malloc(CIF_MAX_SSIZE);
00414 
00415 
00416                           for (i = 0; i < (int) urp[rtype].nrecords; i++) {
00417                                 if (fread ((char *)_cif_map_buffer,
00418                                            _Cif_shortsize[rtype][_Cif_filetbl[cifd].version],
00419                                            1, fd) != 1) IO_ERROR;
00420 
00421                                 (void) _Cif_binary_map_version(rtype, _cif_map_buffer, cr);
00422 
00423                                 if ((n = _Cif_binread (cifd, rtype, cr, fd)) < 0)
00424                                         return (n);
00425                                 cr = (struct Cif_generic *)((char *)cr +
00426                                         _Cif_structsize[rtype][_Cif_filetbl[cifd].return_version]);
00427                               }
00428                         }
00429 
00430                       }
00431 
00432 
00433                 /*
00434                  * The cif_callsite record has a link field which points at the
00435                  * next callsite matching this entry point
00436                  */
00437 
00438                 if (rtype == CIF_CALLSITE) {
00439 
00440                   struct Cif_callsite *cs = (struct Cif_callsite *) *rptr;
00441                   int i;
00442 
00443                   for (i = 0; i < nrecords - 1; i++) {
00444                     if (cs[i].entryid == cs[i+1].entryid)
00445                       cs[i].link = &cs[i+1];
00446                   }
00447 
00448                 }
00449             }
00450         return (nrecords);
00451     }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines