Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
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/cifopen.c 30.6 05/22/97 11:49:31"; 00038 00039 00040 /* 00041 * Cif_Open opens a compiler input input file, either the original ASCII 00042 * format or the compressed binary format. For input files if the "rtypes" 00043 * argument is not NULL, it represents a zero terminated array of record type 00044 * values. Only records of the types selected will be returned by cifgetrec. 00045 * If "rtypes" is NULL, all record types will be returned. 00046 * 00047 * tabs are set to be read with tab spacing = 3 00048 */ 00049 00050 #define CIF_VERSION 3 00051 00052 #ifdef _ABSOFT 00053 #include "cif.h" 00054 #else 00055 #include <cif.h> 00056 #endif 00057 00058 #include <stdlib.h> 00059 #include <stdio.h> /* for fileno() */ 00060 #include <string.h> /* for strdup() */ 00061 #include <sys/types.h> 00062 #include <sys/stat.h> 00063 00064 #define DEFGLOBAL 00065 #include "cif_int.h" 00066 00067 /* fileno() and strdup() are in the Unix standard but not C */ 00068 #if !(defined(__sgi) || defined(__sun) || defined(__alpha)) 00069 extern int fileno(FILE *stream); 00070 /* On other systems this is a macro */ 00071 #endif 00072 extern char *strdup(const char *s); 00073 00074 00075 #define HDRBUF_SIZE 128 /* size of buffer used to read the file header */ 00076 #define HDRTOKENS 10 /* number of tokens in header before tools field */ 00077 00078 00079 00080 /* The cif version number == value of CIF_VERSION 00081 * picked up by Cif_Open function through the use of 00082 * alternative entries to it depending on the value of 00083 * CIF_VERSION. Used in cifdup.c to allow Cif_Duplicate 00084 * to know what version cif to create and copy, and in 00085 * ciffree.c for Cif_Free to know what storage to free. 00086 */ 00087 00088 int _cif_version = 0; 00089 00090 00091 #undef Cif_Open /* ensure that we don't try to map this to Cif_Open_Vx */ 00092 00093 00094 /* Special case of cif_open for applications compiled with CIF_VERSION == 1, 00095 which is the default. A check is made that they are not trying to open 00096 a cif with a version greater than (ie, > 1) the library that they 00097 were compiled with. Probably just catches applications that want to read 00098 a version 2 cif, but haven't set CIF_VERSION 2 before including cif.h */ 00099 00100 int Cif_Open_V1 00101 #ifdef __STDC__ 00102 (char *filename, char *optype, int *rtypes, int version) 00103 #else 00104 (filename, optype, rtypes, version) 00105 char *filename; /* file name */ 00106 char *optype; /* open type */ 00107 int *rtypes; /* ptr to array of selected record types */ 00108 int version; /* CIF version expected by tools */ 00109 #endif 00110 { 00111 00112 /* We can only enter this function if CIF_VERSION used by the application 00113 is set to 1, so if the same application is trying to read a cif version > 1, 00114 the data structures wont match, so better to issue the error now than later */ 00115 00116 if (version > 1) 00117 return (CIF_EXP_VERS); 00118 00119 _cif_version = 1; /* record the CIF_VERSION in use */ 00120 00121 /* call the real cif open */ 00122 00123 return( Cif_Open(filename, optype, rtypes, version) ); 00124 00125 } 00126 00127 /* Special case of cif_open for applications compiled with CIF_VERSION == 2. 00128 A check is made that they are not trying to open 00129 a cif with a version less than (ie, < 2) the library that they 00130 were compiled with. If they compile with version 2, they have to read version 2 */ 00131 00132 int Cif_Open_V2 00133 #ifdef __STDC__ 00134 (char *filename, char *optype, int *rtypes, int version) 00135 #else 00136 (filename, optype, rtypes, version) 00137 char *filename; /* file name */ 00138 char *optype; /* open type */ 00139 int *rtypes; /* ptr to array of selected record types */ 00140 int version; /* CIF version expected by tools */ 00141 #endif 00142 { 00143 00144 /* We can only enter this function if CIF_VERSION used by the application 00145 is set to 2, so if the same application is trying to read a cif version < 2, 00146 the data structures wont match, so better to issue the error now than later */ 00147 00148 if (version < 2) 00149 return (CIF_EXP_VERS2); 00150 00151 _cif_version = 2; /* record the CIF_VERSION in use */ 00152 00153 /* call the real cif open */ 00154 00155 return( Cif_Open(filename, optype, rtypes, version) ); 00156 00157 } 00158 00159 00160 /* 00161 * As above + added a check to see of the cif.h in use matches what this 00162 * library was compiled with...looks at CIF_SUB_VERSION_2 which must match 00163 * the sub_version passed. See cif_open macros in cif.h for more details. 00164 */ 00165 00166 int Cif_Open_V2_1 00167 #ifdef __STDC__ 00168 (char *filename, char *optype, int *rtypes, int version, int sub_version) 00169 #else 00170 (filename, optype, rtypes, version, sub_version) 00171 char *filename; /* file name */ 00172 char *optype; /* open type */ 00173 int *rtypes; /* ptr to array of selected record types */ 00174 int version; /* CIF version expected by tools */ 00175 int sub_version; 00176 #endif 00177 { 00178 00179 /* We can only enter this function if CIF_VERSION used by the application 00180 is set to 2, so if the same application is trying to read a cif version < 2, 00181 the data structures wont match, so better to issue the error now than later */ 00182 00183 if (version < 2) 00184 return (CIF_EXP_VERS2); 00185 00186 if (sub_version != CIF_SUB_VERSION_2) 00187 return(CIF_SUBVER); 00188 00189 _cif_version = 2; /* record the CIF_VERSION in use */ 00190 00191 /* call the real cif open */ 00192 00193 return( Cif_Open(filename, optype, rtypes, version) ); 00194 00195 } 00196 /* 00197 * As above for version 3 00198 */ 00199 00200 int Cif_Open_V3_1 00201 #ifdef __STDC__ 00202 (char *filename, char *optype, int *rtypes, int version, int sub_version) 00203 #else 00204 (filename, optype, rtypes, version, sub_version) 00205 char *filename; /* file name */ 00206 char *optype; /* open type */ 00207 int *rtypes; /* ptr to array of selected record types */ 00208 int version; /* CIF version expected by tools */ 00209 int sub_version; 00210 #endif 00211 { 00212 00213 /* We can only enter this function if CIF_VERSION used by the application 00214 is set to 3, so if the same application is trying to read a cif 00215 version < 3, the data structures wont match, so better to issue the 00216 error now than later */ 00217 00218 if (version < 3) 00219 return (CIF_EXP_VERS2); 00220 00221 if (sub_version != CIF_SUB_VERSION_3) 00222 return(CIF_SUBVER); 00223 00224 _cif_version = 3; /* record the CIF_VERSION in use */ 00225 00226 /* call the real cif open */ 00227 00228 return( Cif_Open(filename, optype, rtypes, version) ); 00229 00230 } 00231 00232 00233 /* 00234 * Cif_Open can only be called directly by a v1 application which 00235 * has been re-linked, but not recompiled. If it had been re-compiled. 00236 * either Cif_Open_V1, or Cif_Open_V2 would be used. If called directly, 00237 * _cif_version will still be 0, so set it to 1 (you can't get v2 records 00238 * without recompiling) and validate against the cif_open version request 00239 */ 00240 00241 int Cif_Open 00242 #ifdef __STDC__ 00243 (char *filename, char *optype, int *rtypes, int version) 00244 #else 00245 (filename, optype, rtypes, version) 00246 char *filename; /* file name */ 00247 char *optype; /* open type */ 00248 int *rtypes; /* ptr to array of selected record types */ 00249 int version; /* CIF version expected by tools */ 00250 #endif 00251 { 00252 int i; 00253 int cx; /* _Cif_filetbl index */ 00254 int *rt; /* pointer to record type selectors */ 00255 FILE *fd; /* file descriptor for file to open */ 00256 char hdrbuf[HDRBUF_SIZE]; /* buffer to contain header record */ 00257 struct stat statbuf; /* file status structure */ 00258 00259 static char ascii_hdrkey[6] = { '2',SEPARATOR,'c','i','f',SEPARATOR }; 00260 static char binary_hdrkey[6] = { SEPARATOR,'c','i','f','b',SEPARATOR }; 00261 static char binary_version = _CIF_INT_VERSION; 00262 00263 int rtype; 00264 struct Cif_generic *rptr; 00265 00266 if (_cif_version == 0) { 00267 00268 /* 00269 * Cif_open must have been called directly by a version 1 application 00270 * (see comment above). Validate the requested version. 00271 */ 00272 00273 if (version > 1) 00274 return (CIF_EXP_VERS); 00275 00276 _cif_version = 1; /* record the CIF_VERSION in use */ 00277 00278 } 00279 00280 00281 00282 /* search for open slot in CIF file table */ 00283 00284 if (version > _CIF_INT_VERSION) 00285 return (CIF_EXP_VERS); 00286 for (cx=0; cx < CIF_FT_SIZE; cx++) 00287 if (_Cif_filetbl[cx].form == NOT_A_CIF) break; 00288 if (cx >= CIF_FT_SIZE) 00289 return (CIF_MAXOPENS); 00290 _Cif_filetbl[cx].ifull = NO; 00291 _Cif_filetbl[cx].seek = NO; 00292 _Cif_filetbl[cx].version = 0; 00293 _Cif_filetbl[cx].return_version = 0; 00294 _Cif_filetbl[cx].ip = NULL; 00295 _Cif_filetbl[cx].mode = CIF_MEM_DEFAULT; 00296 00297 /* open the file */ 00298 00299 if (strcmp (optype, "r") == 0 || strcmp (optype, "w") == 0) 00300 _Cif_filetbl[cx].optype = *optype; 00301 else 00302 return (CIF_BADREQ); 00303 if (strcmp(filename, "-") == 0) { 00304 if (*optype == 'r') 00305 fd = stdin; 00306 else 00307 fd = stdout; 00308 } 00309 else if ((fd = fopen(filename, optype)) == NULL) 00310 return (CIF_SYSERR); 00311 00312 00313 /* if input file, allocate buffer and verify file format then process 00314 * the record selection mask */ 00315 00316 if (*optype == 'r') { 00317 00318 if (fread (hdrbuf, sizeof(char), 6, fd) != 6) { 00319 (void) fclose (fd); 00320 return (CIF_NOTCIF); 00321 } 00322 00323 else if (strncmp (hdrbuf, ascii_hdrkey, 6) == 0) { 00324 00325 /* ASCII file, set file format and reset file position to beginning */ 00326 00327 _Cif_filetbl[cx].form = ASCII_CIF; 00328 if ((_Cif_filetbl[cx].ip = malloc (CIF_BUFSIZE)) == NULL) 00329 return (CIF_NOMEM); 00330 (void) strncpy (_Cif_filetbl[cx].ip, hdrbuf, 6); 00331 if (fgets (_Cif_filetbl[cx].ip+6, CIF_BUFSIZE-6, fd) == NULL) 00332 IO_ERROR; 00333 i = atoi(_Cif_filetbl[cx].ip+7); 00334 if (i > _CIF_INT_VERSION) 00335 return (CIF_FILE_VERS); 00336 00337 _Cif_filetbl[cx].version = i; /* version of cif on disk */ 00338 _Cif_filetbl[cx].return_version = version; /* version that the user wants */ 00339 00340 _Cif_filetbl[cx].ifull = YES; 00341 } 00342 00343 else if (strncmp (hdrbuf, binary_hdrkey, 6) == 0) { 00344 00345 /* Binary file, set file format. Read CIF version and validate. */ 00346 00347 _Cif_filetbl[cx].form = BINARY_CIF; 00348 if (fread (hdrbuf, sizeof(char), 1, fd) != 1) 00349 IO_ERROR; 00350 if (hdrbuf[0] > _CIF_INT_VERSION) 00351 return (CIF_FILE_VERS); 00352 00353 _Cif_filetbl[cx].version = hdrbuf[0]; /* version of cif on disk */ 00354 _Cif_filetbl[cx].return_version = version; /* version that the user wants */ 00355 00356 } 00357 00358 else 00359 return (CIF_NOTCIF); 00360 00361 if (rtypes == NULL) 00362 for (i = 0; i < CIF_MAXRECORD; i++) _Cif_filetbl[cx].rmask[i] = '\1'; 00363 else { 00364 for (i = 0; i < CIF_MAXRECORD; i++) _Cif_filetbl[cx].rmask[i] = '\0'; 00365 for (rt = rtypes; *rt != 0; rt++) 00366 _Cif_filetbl[cx].rmask[*rt] = '\1'; 00367 } 00368 00369 /* Take out records that the requested cif version doesn't know about */ 00370 00371 if (version == 1) { 00372 _Cif_filetbl[cx].rmask[CIF_C_LINT_DIRECTIVE] = '\0'; 00373 _Cif_filetbl[cx].rmask[CIF_C_MACRO_DEF] = '\0'; 00374 _Cif_filetbl[cx].rmask[CIF_C_MACRO_UNDEF] = '\0'; 00375 _Cif_filetbl[cx].rmask[CIF_C_MACRO_USAGE] = '\0'; 00376 _Cif_filetbl[cx].rmask[CIF_C_ENTRY_END] = '\0'; 00377 00378 _Cif_filetbl[cx].rmask[CIF_CDIR] = '\0'; 00379 _Cif_filetbl[cx].rmask[CIF_CDIR_DOSHARED] = '\0'; 00380 _Cif_filetbl[cx].rmask[CIF_GEOMETRY] = '\0'; 00381 _Cif_filetbl[cx].rmask[CIF_CONTINUATION] = '\0'; 00382 _Cif_filetbl[cx].rmask[CIF_TRANSFORM] = '\0'; 00383 00384 _Cif_filetbl[cx].rmask[CIF_F90_CALLSITE] = '\0'; 00385 _Cif_filetbl[cx].rmask[CIF_F90_COMBLK] = '\0'; 00386 _Cif_filetbl[cx].rmask[CIF_F90_CONST] = '\0'; 00387 _Cif_filetbl[cx].rmask[CIF_F90_ENTRY] = '\0'; 00388 _Cif_filetbl[cx].rmask[CIF_F90_LOOP] = '\0'; 00389 _Cif_filetbl[cx].rmask[CIF_F90_DERIVED_TYPE] = '\0'; 00390 _Cif_filetbl[cx].rmask[CIF_F90_LABEL] = '\0'; 00391 _Cif_filetbl[cx].rmask[CIF_F90_NAMELIST] = '\0'; 00392 _Cif_filetbl[cx].rmask[CIF_F90_OBJECT] = '\0'; 00393 _Cif_filetbl[cx].rmask[CIF_F90_MISC_OPTS] = '\0'; 00394 _Cif_filetbl[cx].rmask[CIF_F90_OPT_OPTS] = '\0'; 00395 _Cif_filetbl[cx].rmask[CIF_F90_BEGIN_SCOPE] = '\0'; 00396 _Cif_filetbl[cx].rmask[CIF_F90_END_SCOPE] = '\0'; 00397 _Cif_filetbl[cx].rmask[CIF_F90_SCOPE_INFO] = '\0'; 00398 _Cif_filetbl[cx].rmask[CIF_F90_USE_MODULE] = '\0'; 00399 _Cif_filetbl[cx].rmask[CIF_F90_RENAME] = '\0'; 00400 _Cif_filetbl[cx].rmask[CIF_F90_INT_BLOCK] = '\0'; 00401 _Cif_filetbl[cx].rmask[CIF_F90_VECTORIZATION] = '\0'; 00402 00403 _Cif_filetbl[cx].rmask[CIF_BE_NODE] = '\0'; 00404 _Cif_filetbl[cx].rmask[CIF_BE_FID] = '\0'; 00405 00406 } 00407 00408 if (version < 3) { 00409 00410 _Cif_filetbl[cx].rmask[CIF_CC_TYPE] = '\0'; 00411 _Cif_filetbl[cx].rmask[CIF_CC_ENTRY] = '\0'; 00412 _Cif_filetbl[cx].rmask[CIF_CC_OBJ] = '\0'; 00413 _Cif_filetbl[cx].rmask[CIF_CC_SUBTYPE] = '\0'; 00414 _Cif_filetbl[cx].rmask[CIF_CC_ENUM] = '\0'; 00415 _Cif_filetbl[cx].rmask[CIF_CC_EXPR] = '\0'; 00416 00417 _Cif_filetbl[cx].rmask[CIF_SRC_POS] = '\0'; 00418 _Cif_filetbl[cx].rmask[CIF_ORIG_CMD] = '\0'; 00419 00420 } 00421 } 00422 00423 else { /* output file so */ 00424 _Cif_filetbl[cx].form = BINARY_CIF; 00425 if (fwrite (binary_hdrkey, sizeof(char), 6, fd) != 6) 00426 return (CIF_SYSERR); 00427 if (fwrite (&binary_version, sizeof(char), 1, fd) != 1) 00428 return (CIF_SYSERR); 00429 00430 /* Set both of the cif versions to the cif_open version; it is 00431 not possible to open a cif as one version and then write 00432 records from another version into it; ie if the users 00433 compiled with v1 then that's what they get for all opens; 00434 likewise for v2 */ 00435 00436 _Cif_filetbl[cx].version = version; /* version of cif on disk */ 00437 _Cif_filetbl[cx].return_version = version; /* version that the user wants */ 00438 } 00439 00440 /* determine if seeks are allowed on file */ 00441 00442 /* 00443 * Note. To get fileno to work on 6.1, use (fileno(fd) & 0xffff) 00444 * as the fileno structure changed slightly and the top however 00445 * many bits need to be masked out. I haven't put this in by 00446 * default as libcif should never be put onto a 6.1 system and 00447 * it seems like a kludge with unknown side effects, so it's best 00448 * to leave out 00449 * 00450 * Okay, so I changed my mind...I'm told that this is a safe 00451 * fix, but I'll leave in the warning above 00452 */ 00453 00454 (void) fstat ((int) (fileno(fd) & 0xffffffff), &statbuf); 00455 _Cif_filetbl[cx].seek = (S_ISREG(statbuf.st_mode) ? YES : NO); 00456 00457 _Cif_filetbl[cx].fd = fd; 00458 00459 /* Make a note of the cif being opened */ 00460 _Cif_filetbl[cx].filename = strdup(filename); 00461 00462 /* 00463 * Assume cif not created specially, cif_lines and cif_conv will 00464 * alter this if they are invoking cif_open indirectly for the user 00465 * and a temporary cif has been opened 00466 */ 00467 _Cif_filetbl[cx].tmp_cif = 0; 00468 00469 00470 if (*optype == 'r' && /* reading from the file */ 00471 _Cif_filetbl[cx].seek == YES && /* Otherwise, we can't backup */ 00472 _Cif_filetbl[cx].return_version > 1) { /* v2 cif or greater */ 00473 00474 /* 00475 * This is really messy, but we want to read ahead until 00476 * the srcfile record is read so that the src file id can 00477 * be put into the cifhdr record. 00478 */ 00479 00480 /* ensure that the file is at the beginning */ 00481 (void) Cif_Setpos(cx, CIF_FIRST_RECORD); 00482 00483 do { 00484 rtype = Cif_Getrecord(cx, &rptr); 00485 } 00486 while (rtype > 0 && rtype != CIF_SRCFILE && 00487 rtype != CIF_UNIT); 00488 00489 if (rtype == CIF_SRCFILE) { 00490 _Cif_filetbl[cx].srcfid = CIFSRC(rptr)->fid; 00491 } 00492 00493 /* Reset, so that it looks like we haven't read anything yet */ 00494 _Cif_filetbl[cx].mode = CIF_MEM_DEFAULT; 00495 } 00496 00497 /* ensure that the file is at the beginning */ 00498 if (_Cif_filetbl[cx].seek == YES) 00499 (void) Cif_Setpos(cx, CIF_FIRST_RECORD); 00500 00501 return (cx); 00502 00503 }