cif_conv.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/cif_conv.c   30.22   12/08/96 14:42:46";
00038 
00039 
00040 /* --------------------------------------------------------------------------
00041  * "cifconv" Compiler Information File reformatter.
00042  * --------------------------------------------------------------------------
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 <malloc.h>
00054 #include <stdio.h>
00055 #include <string.h>
00056 #include <stdlib.h>
00057 #include <unistd.h>
00058 #include "unitrecord.h"
00059 #include "cif_int.h"
00060 
00061 #include <sys/types.h>
00062 #include <sys/stat.h>
00063 
00064 extern char *strdup(const char *s);
00065 extern char *tempnam(const char *dir, const char *pfx);
00066 
00067 extern void exit (int);
00068 /*
00069 extern char *getenv (const char *);
00070 */
00071 enum Boolean {False, True};
00072 
00073 
00074 static int sortfile (struct Cif_generic *);
00075 static int copy_units (void);
00076 static int write_header (void);
00077 static int get_srcfid (void);
00078 static int write_unit (int, enum Boolean, enum Boolean);
00079 int cif_VerifyCanWrite( char *file );
00080 static int lang;
00081 
00082 /*
00083  * global return code value, in case cifconv needs to exit so that the
00084  * correct error flag can be passed back to the caller
00085  */
00086 static int cifconv_return_code = 0;
00087 
00088 static void free_copied_blocks();
00089 
00090 #define CIFCONV_INVALID_RECORDS 2
00091 
00092 #undef Cif_Cifconv  /* ensure that we don't try to map this to Cif_Cifconv_Vx */
00093 
00094 #define MEM_ERROR { \
00095         (void) fprintf (stderr, "libcif: %s\n", Cif_Errstring(CIF_NOMEM)); \
00096         exit (1); \
00097 }
00098 
00099 #define OUT_ERROR(STR,FD,STATUS) { \
00100         (void) fprintf (stderr, "libcif: error %s file %s - %s\n", \
00101                 STR, (FD==outfd ? global_outfile : tfile), Cif_Errstring(STATUS)); \
00102         exit (STATUS); \
00103 }
00104 
00105 /* --- file names and file descriptors --- */
00106 static int infd;                                        /* input cif descriptor */
00107 static int outfd;                                       /* output cif descriptor */
00108 static int tmpfd = -1;                                  /* temporary file cif descriptor */
00109 static char *tfile = NULL;              /* pointer to temporary file name */
00110 static long fdirpos;                            /* file positon of file directory */
00111 static enum Boolean canpos = False;             /* generate positioning info flag */
00112 static int *global_nuses = (int *) NULL;        /* count of use's per usage used in merge_usages */
00113 static int global_nuses_allocated = 0;
00114 
00115 #ifdef DEBUG
00116         static FILE *dfd;                               /* file descriptor for debug file output */
00117         static FILE *sfd;                               /* file descriptor for standard output */
00118         void dump_patbl ();
00119         int valid_patbl ();
00120 #endif
00121 
00122 /* --- id remapping data --- */
00123 #define ID_BUMP 500                     /* amount to increment tbl size */
00124 static enum Boolean Remap_id;           /* set if ids need to be remapped */
00125 struct Id_tbl {
00126         long *tbl;                      /* ptr to array of original id values */
00127         int max;                        /* current maximum size of tbl */
00128         int cur;                        /* index of next available slot in tbl */
00129 };
00130 static struct Id_tbl sid;               /* symbol id remapping data */
00131 #ifdef REMAP_FID
00132 static struct Id_tbl fid;               /* file id remapping data */
00133 #endif
00134 
00135 static enum Boolean first_time = True;
00136 
00137 #ifdef REMAP_FID
00138 /* The mapped srcfid to go into the cif_cifhdr record */
00139 static int srcfid = 0;
00140 #endif
00141 
00142 /* --- pointer array management structure --- */
00143 static struct {
00144         struct Cif_generic **aptr;      /* ptr to array of ptrs to record structs */
00145         int psize;                      /* current allocated size of ptr array */
00146         int next;                       /* index of next available slot in ptr array */
00147 } patbl[CIF_MAXRECORD];
00148 
00149 static char *global_outfile;  /*
00150                                * allows output filename to be printed from
00151                                * anywhere when an error condition occurs
00152                                */
00153 /* global_error_report is set to true if the cif_cifconv
00154  * user wants errors reported to stderr. Error such as
00155  * a usage record not having a matching definition record.
00156  * If false, these errors are ignored.
00157  */
00158 static enum Boolean global_error_report = False;
00159 
00160 /* --- pointer array increment values --- */
00161 static const int pabump[CIF_MAXRECORD] = {
00162         0,              /* 00 = unused */
00163         100,            /* 01 = CIF_CALLSITE */
00164         1,              /* 02 = CIF_CIFHDR */
00165         100,            /* 03 = CIF_COMBLK */
00166         200,            /* 04 = CIF_CONST */
00167         100,            /* 05 = CIF_CDIR */
00168         100,            /* 06 = CIF_ENTRY */
00169         100,            /* 07 = CIF_FILE */
00170         100,            /* 08 = CIF_LOOP */
00171         100,            /* 09 = CIF_INCLUDE */
00172         200,            /* 10 = CIF_LABEL */
00173         100,            /* 11 = CIF_MESSAGE */
00174         100,            /* 12 = CIF_NAMELIST */
00175         400,            /* 13 = CIF_OBJECT */
00176         1,              /* 14 = CIF_SRCFILE */
00177         1,              /* 15 = CIF_SUMMARY */
00178         100,            /* 16 = CIF_CDIR_DOSHARED */
00179         1,              /* 17 = CIF_UNIT */
00180         1,              /* 18 = CIF_ENDUNIT */
00181         1000,           /* 19 = CIF_USAGE */
00182         100,            /* 20 = CIF_ND_MSG */
00183         1,              /* 21 = CIF_EDOPTS */
00184         1,              /* 22 = CIF_MACH_CHAR */
00185         1,              /* 23 = CIF_MISC_OPTS */
00186         1,              /* 24 = CIF_OPT_OPTS */
00187         1000,           /* 25 = CIF_STMT_TYPE */
00188         100,            /* 26 = CIF_GEOMETRY */
00189         100,            /* 27 = CIF_CONTINUATION */
00190         100,            /* 28 = CIF_F90_CALLSITE */
00191         100,            /* 29 = CIF_F90_COMBLK */
00192         200,            /* 30 = CIF_F90_CONST */
00193         100,            /* 31 = CIF_F90_ENTRY */
00194         100,            /* 32 = CIF_F90_LOOP */
00195         100,            /* 33 = CIF_F90_DERIVED_TYPE */
00196         200,            /* 34 = CIF_F90_LABEL */
00197         100,            /* 35 = CIF_F90_NAMELIST */
00198         400,            /* 36 = CIF_F90_OBJECT */
00199         1,              /* 37 = CIF_F90_MISC_OPTS */
00200         1,              /* 38 = CIF_F90_OPT_OPTS */
00201         100,            /* 39 = CIF_F90_BEGIN_SCOPE */
00202         100,            /* 40 = CIF_F90_END_SCOPE */
00203         100,            /* 41 = CIF_F90_SCOPE_INFO */
00204         100,            /* 42 = CIF_F90_USE_MODULE */
00205         100,            /* 43 = CIF_F90_RENAME */
00206         100,            /* 44 = CIF_F90_INT_BLOCK */
00207         100,            /* 45 = CIF_F90_VECTORIZATION */
00208         100,            /* 46 = CIF_BE_NODE */
00209         100,            /* 47 = CIF_TRANSFORM */
00210         1,              /* 48 = CIF_FILEDIR */
00211         1,              /* 49 = CIF_UNITDIR */
00212         100,            /* 50 = CIF_BE_FID */
00213         400,            /* 51= CIF_C_TAG */
00214         1,              /* 52= CIF_C_OPTS */
00215         100,            /* 53= CIF_C_MESSAGE */
00216         200,            /* 54= CIF_C_CONST */
00217         100,            /* 55= CIF_C_ENTRY */
00218         400,            /* 56= CIF_C_OBJECT */
00219         200,            /* 57= CIF_C_LINT_DIRECTIVE */
00220         200,            /* 58= CIF_C_MACRO_DEF */
00221         200,            /* 59= CIF_C_MACRO_UNDEF */
00222         400,            /* 60= CIF_C_MACRO_USAGE */
00223         100,            /* 61= CIF_C_ENTRY_END */
00224         0,0,0,0,0,0,0,0, /* 62-69 */
00225         1,              /* 70= CIF_ORIG_CMD */
00226         0,0,0,0,0,0,0,0,0, /* 71-79 */
00227         100,            /* 80= CIF_CC_TYPE */
00228         100,            /* 81= CIF_CC_ENTRY */
00229         100,            /* 82= CIF_CC_OBJ */
00230         100,            /* 83= CIF_CC_SUBTYPE */
00231         100,            /* 84= CIF_CC_ENUM */
00232         100,            /* 85= CIF_CC_EXPR */
00233         100             /* 86= CIF_SRC_POS */
00234 
00235 
00236 };
00237 
00238 /* --- function pointer array - qsort structure comparison routines --- */
00239 static int comp_callsite (struct Cif_callsite **, struct Cif_callsite **);
00240 static int comp_comblk (struct Cif_comblk **, struct Cif_comblk **);
00241 static int comp_const (struct Cif_const **, struct Cif_const **);
00242 static int comp_entry (struct Cif_entry **, struct Cif_entry **);
00243 static int comp_file (struct Cif_file **, struct Cif_file **);
00244 static int comp_label (struct Cif_label **, struct Cif_label **);
00245 static int comp_loop (struct Cif_loop **, struct Cif_loop **);
00246 static int comp_message (struct Cif_message **, struct Cif_message **);
00247 static int comp_namelist (struct Cif_namelist **, struct Cif_namelist **);
00248 static int comp_object (struct Cif_object **, struct Cif_object **);
00249 static int comp_stmt_type (struct Cif_stmt_type **,struct Cif_stmt_type **);
00250 static int comp_usage (struct Cif_usage **, struct Cif_usage **);
00251 static int comp_c_tag (struct Cif_c_tag **, struct Cif_c_tag **);
00252 static int comp_c_message (struct Cif_c_message **, struct Cif_c_message **);
00253 static int comp_c_const (struct Cif_c_const **, struct Cif_c_const **);
00254 static int comp_c_entry (struct Cif_c_entry **, struct Cif_c_entry **);
00255 static int comp_c_object (struct Cif_c_object **, struct Cif_c_object **);
00256 static int comp_c_lint_directive (struct Cif_c_lint_directive **, struct Cif_c_lint_directive **);
00257 static int comp_c_macro_def (struct Cif_c_macro_def **, struct Cif_c_macro_def **);
00258 static int comp_c_macro_undef (struct Cif_c_macro_undef **, struct Cif_c_macro_undef **);
00259 static int comp_c_macro_usage (struct Cif_c_macro_usage **, struct Cif_c_macro_usage **);
00260 static int comp_c_entry_end (struct Cif_c_entry_end **, struct Cif_c_entry_end **);
00261 
00262 static int comp_cdir (struct Cif_cdir **, struct Cif_cdir **);
00263 static int comp_cdir_doshared (struct Cif_cdir_doshared **, struct Cif_cdir_doshared **);
00264 static int comp_geometry (struct Cif_geometry **, struct Cif_geometry **);
00265 static int comp_continuation (struct Cif_continuation **, struct Cif_continuation **);
00266 static int comp_transform (struct Cif_transform **, struct Cif_transform **);
00267 
00268 #ifndef CRAY2
00269 static int comp_f90_callsite (struct Cif_f90_callsite **, struct Cif_f90_callsite **);
00270 static int comp_f90_comblk (struct Cif_f90_comblk **, struct Cif_f90_comblk **);
00271 static int comp_f90_const (struct Cif_f90_const **, struct Cif_f90_const **);
00272 static int comp_f90_entry (struct Cif_f90_entry **, struct Cif_f90_entry **);
00273 static int comp_f90_loop (struct Cif_f90_loop **, struct Cif_f90_loop **);
00274 static int comp_f90_derived_type (struct Cif_f90_derived_type **, struct Cif_f90_derived_type **);
00275 static int comp_f90_label (struct Cif_f90_label **, struct Cif_f90_label **);
00276 static int comp_f90_namelist (struct Cif_f90_namelist **, struct Cif_f90_namelist **);
00277 static int comp_f90_object (struct Cif_f90_object **, struct Cif_f90_object **);
00278 static int comp_f90_begin_scope (struct Cif_f90_begin_scope **, struct Cif_f90_begin_scope **);
00279 static int comp_f90_end_scope (struct Cif_f90_end_scope **, struct Cif_f90_end_scope **);
00280 static int comp_f90_scope_info (struct Cif_f90_scope_info **, struct Cif_f90_scope_info **);
00281 static int comp_f90_use_module (struct Cif_f90_use_module **, struct Cif_f90_use_module **);
00282 static int comp_f90_rename (struct Cif_f90_rename **, struct Cif_f90_rename **);
00283 static int comp_f90_int_block (struct Cif_f90_int_block **, struct Cif_f90_int_block **);
00284 static int comp_f90_vectorization (struct Cif_f90_vectorization **, struct Cif_f90_vectorization **);
00285 
00286 #endif /* CRAY2 */
00287 
00288 static int comp_cc_type (struct Cif_cc_type **, struct Cif_cc_type **);
00289 static int comp_cc_entry (struct Cif_cc_entry **, struct Cif_cc_entry **);
00290 static int comp_cc_obj (struct Cif_cc_obj **, struct Cif_cc_obj **);
00291 static int comp_cc_subtype (struct Cif_cc_subtype **, struct Cif_cc_subtype **);
00292 static int comp_cc_enum (struct Cif_cc_enum **, struct Cif_cc_enum **);
00293 static int comp_cc_expr (struct Cif_cc_expr **, struct Cif_cc_expr **);
00294 
00295 static int comp_src_pos (struct Cif_src_pos **, struct Cif_src_pos **);
00296 static int comp_orig_cmd (struct Cif_orig_cmd **, struct Cif_orig_cmd **);
00297 
00298 static int (*qcompare[CIF_MAXRECORD]) () = {
00299         0,                              /* 00 */
00300         comp_callsite,                  /* 01 = CIF_CALLSITE */
00301         0,                              /* 02 */
00302         comp_comblk,                    /* 03 = CIF_COMBLK */
00303         comp_const,                     /* 04 = CIF_CONST */
00304         comp_cdir,                      /* 05 = CIF_CDIR */
00305         comp_entry,                     /* 06 = CIF_ENTRY */
00306         comp_file,                      /* 07 = CIF_FILE */
00307         comp_loop,                      /* 08 = CIF_LOOP */
00308         0,                              /* 09 */
00309         comp_label,                     /* 10 = CIF_LABEL */
00310         comp_message,                   /* 11 = CIF_MESSAGE */
00311         comp_namelist,                  /* 12 = CIF_NAMELIST */
00312         comp_object,                    /* 13 = CIF_OBJECT */
00313         0,0,                            /* 14, 15 */
00314         comp_cdir_doshared,             /* 16 = CIF_CDIR_DOSHARED */
00315         0,0,                            /* 17, 18 */
00316         comp_usage,                     /* 19 = CIF_USAGE */
00317         0,0,0,0,0,                      /* 20-24 */
00318         comp_stmt_type,                 /* 25 = CIF_STMT_TYPE */
00319         comp_geometry,                  /* 26 = CIF_GEOMETRY */
00320         comp_continuation,              /* 27 = CIF_CONTINUATION */
00321 #ifndef CRAY2
00322         comp_f90_callsite,              /* 28 = CIF_F90_CALLSITE */
00323         comp_f90_comblk,                /* 29 = CIF_F90_COMBLK */
00324         comp_f90_const,                 /* 30 = CIF_F90_CONST */
00325         comp_f90_entry,                 /* 31 = CIF_F90_ENTRY */
00326         comp_f90_loop,                  /* 32 = CIF_F90_LOOP */
00327         comp_f90_derived_type,          /* 33 = CIF_F90_DERIVED_TYPE */
00328         comp_f90_label,                 /* 34 = CIF_F90_LABEL */
00329         comp_f90_namelist,              /* 35 = CIF_F90_NAMELIST */
00330         comp_f90_object,                /* 36 = CIF_F90_OBJECT */
00331 #else
00332         0,0,0,0,0,0,0,0,0,
00333 #endif /* CRAY2 */
00334         0,                              /* 37 = CIF_F90_MISC_OPTS */
00335         0,                              /* 38 = CIF_F90_OPT_OPTS */
00336 #ifndef CRAY2
00337         comp_f90_begin_scope,           /* 39 = CIF_F90_BEGIN_SCOPE */
00338         comp_f90_end_scope,             /* 40 = CIF_F90_END_SCOPE */
00339         comp_f90_scope_info,            /* 41 = CIF_F90_SCOPE_INFO */
00340         comp_f90_use_module,            /* 42 = CIF_F90_USE_MODULE */
00341         comp_f90_rename,                /* 43 = CIF_F90_RENAME */
00342         comp_f90_int_block,             /* 44 = CIF_F90_INT_BLOCK */
00343         comp_f90_vectorization,         /* 45 = CIF_F90_VECTORIZATION */
00344 #else
00345         0,0,0,0,0,0,0,
00346 #endif /* CRAY2 */
00347         0,                              /* 46 = CIF_BE_NODE */
00348         comp_transform,                 /* 47 = CIF_TRANSFORM */
00349         0, 0,                           /* 48, 49 */
00350         0,                              /* 50 = CIF_BE_FID */
00351         comp_c_tag,                     /* 51= CIF_C_TAG */
00352         0,                              /* 52= CIF_C_OPTS */
00353         comp_c_message,                 /* 53= CIF_C_MESSAGE */
00354         comp_c_const,                   /* 54= CIF_C_CONST */
00355         comp_c_entry,                   /* 55= CIF_C_ENTRY */
00356         comp_c_object,                  /* 56= CIF_C_OBJECT */
00357         comp_c_lint_directive,          /* 57= CIF_C_LINT_DIRECTIVE */
00358         comp_c_macro_def,               /* 58= CIF_C_MACRO_DEF */
00359         comp_c_macro_undef,             /* 59= CIF_C_MACRO_UNDEF */
00360         comp_c_macro_usage,             /* 60= CIF_C_MACRO_USAGE*/
00361         comp_c_entry_end,               /* 61= CIF_C_ENTRY_END */
00362         0,0,0,0,0,0,0,0,                /* 62-69 */
00363         comp_orig_cmd,                  /* 70= CIF_ORIG_CMD */
00364         0,0,0,0,0,0,0,0,0,              /* 71-79 */
00365         comp_cc_type,                   /* 80= CIF_CC_TYPE */
00366         comp_cc_entry,                  /* 81= CIF_CC_ENTRY */
00367         comp_cc_obj,                    /* 82= CIF_CC_OBJ */
00368         comp_cc_subtype,                /* 83= CIF_CC_SUBTYPE */
00369         comp_cc_enum,                   /* 84= CIF_CC_ENUM */
00370         comp_cc_expr,                   /* 85= CIF_CC_EXPR */
00371         comp_src_pos                    /* 86= CIF_SRC_POS */
00372 };
00373 
00374 /* --- forward references --- */
00375 static void addstruct (struct Cif_generic *);   
00376 static void addunit (struct Cif_generic *);
00377 static void add_id (struct Id_tbl *, long);
00378 static int comp_ids (long *, long *);
00379 static long get_max_fid (void);
00380 static long get_max_sid (void);
00381 static void init_id (struct Id_tbl *);
00382 static void makeudir (void);
00383 static void remap_files (void);
00384 static void remap_symbols (void);
00385 
00386 
00387 /* returns True if file_2 is older than file_1 */
00388 
00389 static int later_date
00390 #ifdef __STDC__
00391           (char *file_1, char *file_2)
00392 #else
00393           (file_1, file_2)
00394 char *file_1, *file_2;
00395 #endif
00396 {
00397   struct stat buf_1, buf_2;
00398 
00399   (void) stat(file_1, &buf_1);
00400   (void) stat(file_2, &buf_2);
00401 
00402   return(buf_2.st_mtime >= buf_1.st_mtime);  
00403 }
00404 
00405 
00406 
00407 /* Function: cif_next_entry */
00408 
00409 static
00410   int cif_next_entry
00411 #ifdef __STDC__
00412         ( int cifd, long *cifpos, struct Cif_generic **cif_record )
00413 #else
00414         ( cifd, cifpos, cif_record )
00415 int cifd;
00416 long *cifpos;
00417 struct Cif_generic **cif_record;
00418 #endif
00419 {
00420   int rtype;
00421 
00422   if ((rtype = Cif_Setpos (cifd, *cifpos)) < 0) {
00423     (void) fprintf(stderr, "libcif: set pos returns %d %s for cifd %d %ld\n",
00424             rtype,
00425             Cif_Errstring(rtype),
00426             cifd,
00427             *cifpos);
00428   }
00429 
00430   if ((rtype = Cif_Getrecord (cifd, cif_record)) < 0) {
00431     (void) fprintf (stderr, "libcif: Unknown record type at %ld for %d: (%d) %s\n",
00432             *cifpos,
00433             cifd,
00434             rtype,
00435             Cif_Errstring(rtype));
00436   }
00437 
00438   *cifpos = Cif_Getpos(cifd);
00439   return(rtype);
00440 }
00441 
00442 
00443 
00444 /*
00445  * cifconv_type returns true if this file is in cifconv format already
00446  * false otherwise.
00447  */
00448 
00449 
00450 static int cifconv_type
00451 #ifdef __STDC__
00452         (char *cif_name)
00453 #else
00454         (cif_name)
00455 char *cif_name;
00456 #endif
00457 {
00458   int cifd;
00459   long filepos = CIF_FIRST_RECORD;
00460   int return_code;
00461   struct Cif_generic *cif_record;
00462 
00463   cifd = Cif_Open(cif_name, "r", NULL, CIF_VERSION);
00464 
00465   if (cifd >= 0 &&
00466       cif_next_entry(cifd, &filepos, &cif_record) == CIF_CIFHDR) {
00467 
00468     return_code = (CIFHDR(cif_record)->form == CIF_FORM_SORTED);
00469     return_code &= (CIFHDR(cif_record)->bintype == CIF_FORM_CIFCONV);
00470 
00471     lang = CIFHDR(cif_record)->lang;  /* note the source language */
00472 
00473     (void) Cif_Close (cifd, CIF_MEM_FREE);
00474     return(return_code);
00475   }
00476   else {
00477     return(0);
00478   }
00479 }
00480 
00481 
00482 /* --------------------------------------------------------------------------
00483  * main opens the input CIF file.  If binary format, it just copies it.  If
00484  * ASCII format, it organizes the records into order, adds directory
00485  * information, and writes out a binary format file.
00486  *
00487  * Record structures are managed by the an array of pointers to structure
00488  * for each type.  As each structure is encountered, a pointer to the
00489  * structure is added to the appropriate pointer array.  The pointer arrays
00490  * are dynamically expanded as needed.  Before writing out the structures,
00491  * the pointer arrays are sorted in the correct order for that type.
00492  * --------------------------------------------------------------------------
00493  */
00494 
00495 static char *Cif_Make_Cifconv
00496 #ifdef __STDC__
00497         (char *infile, char *outfile, int *rtypes)
00498 #else
00499         (infile, outfile, rtypes)
00500 char *infile;
00501 char *outfile;
00502 int *rtypes;
00503 #endif
00504 {
00505 
00506         int arg;                        /* argument counter */
00507         struct Cif_generic *cifp;       /* CIF structure pointer */
00508         int ret;
00509 
00510 #ifdef DEBUG
00511         dfd = fopen ("debug", "w");
00512         sfd = stdout;
00513 #endif
00514 
00515         /*
00516          * Note the filename to allow it to be printed
00517          * in error messages
00518          */
00519         global_outfile = infile;
00520 
00521         /* Open the input and output files */
00522 
00523         if ((infd = Cif_Open(infile, "r", rtypes, CIF_VERSION)) < 0) {
00524           /* store the return code for returning from Cif_Cifconv */
00525           cifconv_return_code = infd;
00526           return ((char *) NULL);
00527         }
00528 
00529 
00530         if ((ret = Cif_Memmode(infd,CIF_MEM_MANAGED)) < 0)  {
00531             (void) fprintf(stderr,"\nlibcif: Unrecoverable internal error - Cif_Memmode\
00532 (%d,CIF_MEM_MANAGED=%d) returns %d:\n\t Possible cause is memory \
00533 expansion request denial by OS\n\t Note -- Internal CIF-Library \
00534 Message:\n\n\t\t \"%s\"\n",
00535                 infd,CIF_MEM_MANAGED,ret,Cif_Errstring(ret));
00536             exit(ret);
00537        }
00538 
00539         if ((outfd = Cif_Open(outfile, "w", NULL, CIF_VERSION)) < 0) {
00540                 (void) Cif_Close(infd, CIF_MEM_FREE);
00541                 cifconv_return_code = outfd; 
00542                 return ((char *) NULL);
00543         }
00544 
00545         /*
00546          * Get the header record.  If the form is sorted, copy the file.
00547          * Otherwise sort it.  
00548          */
00549 
00550         if ((arg = Cif_Getrecord (infd, &cifp)) == CIF_CIFHDR) {
00551 
00552                 if (CIFHDR(cifp)->form == CIF_FORM_SORTED) {
00553                         (void) free(outfile);
00554                         return(strdup(infile));
00555                 }
00556                 else {
00557                         if (CIFHDR(cifp)->cont_id == CIF_ID_NONCONTIG) {
00558 
00559                                 /* Make sure the old memory is freed off */
00560 
00561                                 if (sid.tbl != (long *) NULL)
00562                                         (void) free(sid.tbl);
00563 
00564                                 if ((sid.tbl = (long *) malloc (sizeof(long)*ID_BUMP)) == NULL)
00565                                         MEM_ERROR;
00566                                 sid.max = ID_BUMP;
00567 
00568 #ifdef REMAP_FID
00569                                 if (fid.tbl != (long *) NULL)
00570                                         (void) free(fid.tbl);
00571 
00572                                 if ((fid.tbl = (long *) malloc (sizeof(long)*ID_BUMP)) == NULL)
00573                                         MEM_ERROR;
00574                                 fid.max = ID_BUMP;
00575 #endif
00576                                 Remap_id = True;
00577                         }
00578                         else
00579                                 Remap_id = False;
00580                         /*
00581                          * sortfile will return -1 iff no units are found,
00582                          * in which case, just copy the infile to the outfile
00583                          * as there's little extra to be done
00584                          */
00585                         if (sortfile (cifp) < 0) {
00586                                 (void) Cif_Close(outfd, CIF_MEM_FREE);
00587                                 unlink(outfile);
00588                                 return(strdup(infile));
00589                         }
00590                 }
00591         }
00592         else {
00593                 if (arg > 0)
00594                         return((char *) NULL);
00595         }
00596 
00597         /* Free up any space allocated via Cif_Duplicate calls */
00598         free_copied_blocks();
00599 
00600         /* Close the files and quit */
00601 
00602         (void) Cif_Close (infd, CIF_MEM_KEEP);
00603         (void) Cif_Close (outfd, CIF_MEM_KEEP);
00604 
00605         /* Close the tmp file as necessary */
00606 
00607         if (tmpfd != -1) {
00608                 (void) Cif_Close (tmpfd, CIF_MEM_KEEP);
00609                 tmpfd = -1;
00610         }
00611 
00612 #ifdef DEBUG
00613         (void) fclose (dfd);
00614 #endif
00615         return(outfile);
00616 }
00617 
00618 
00619 /*
00620  * An unpublished routine, used by xbrowse to set the location of
00621  * .TT files. xbrowse does all validation of the directory, so no
00622  * need to do any checking here
00623  */
00624 
00625 static char *cif_tt_dir = (char *) NULL;
00626 
00627 void Cif_ConvDir
00628 #ifdef __STDC__
00629         (char *dir)
00630 #else
00631         (dir)
00632 char *dir;
00633 #endif
00634 {
00635     cif_tt_dir = dir;
00636 }
00637 
00638 
00639 /* Join two strings together */
00640 static char *concat
00641 #ifdef _STDC__
00642         ( char *str1, char *str2 )
00643 #else
00644         ( str1, str2 )
00645 char *str1, *str2;
00646 #endif
00647 {
00648   char *buf;
00649 
00650   buf = (char *) malloc (sizeof(char) * (strlen(str1) + strlen(str2) + 1));
00651   sprintf(buf, "%s%s",str1, str2);
00652   return(buf);
00653 }
00654 
00655 /* Verify that the directory passed exists and is writable */
00656 int assertCanWriteDir
00657 #ifdef __STDC__
00658         (char *dir)
00659 #else
00660         (dir)
00661 char *dir;
00662 #endif
00663 {
00664   struct stat buf;
00665   int mode;
00666   char * test_file = concat(dir,"/write_test");
00667   FILE * fd;
00668 
00669   mode = stat(dir, &buf);
00670 
00671   if (mode == 0 &&
00672       S_ISDIR(buf.st_mode)) {
00673     if (NULL == (fd = fopen(test_file,"w"))) {
00674       return(0);  /* directory is not writable */
00675     };
00676     fclose(fd);
00677     unlink(test_file);
00678   }
00679   else {
00680    return(0);
00681   }
00682 
00683   free(test_file);
00684 
00685   return(1); /* directory exists and is writable */
00686 }      
00687 
00688 static char *cif_convert_to_cifconv
00689 #ifdef __STDC__
00690         (char *filename, int keep, int *tmp_cif, int *rtypes)
00691 #else
00692         (filename, keep, tmp_cif, rtypes)
00693 char *filename;
00694 int keep;
00695 int *tmp_cif;
00696 int *rtypes;
00697 #endif
00698 {
00699     char *value;
00700     char *cifdir = (char *) NULL;
00701     char *cifdir_file = (char *) NULL;
00702     char *tt_file = (char *) NULL;
00703     char *outfile = (char *) NULL;
00704     char *create_cif_file = (char *) NULL;
00705     char *tmpdir = (char *) NULL;
00706 
00707     /* Assume that a tmp file will not be created, until proved otherwise */
00708 
00709     *tmp_cif = 0;
00710 
00711     /* 1. check if the file is already a cifconv file */
00712 
00713     if (cifconv_type( filename ) == 1)
00714         return(strdup(filename));
00715 
00716 
00717     /* See if cif_convdir has been called to set the location of .TT files */
00718 
00719     if (cif_tt_dir != (char *) NULL) {
00720 
00721         cifdir = cif_tt_dir;
00722 
00723         tt_file = (char *) malloc(sizeof(char) *
00724                                   (strlen(cif_tt_dir) + 
00725                                    strlen(cif_basename(filename)) +
00726                                    3));
00727 
00728         (void) sprintf(tt_file, "%s/%sT", cif_tt_dir,
00729                        cif_basename(filename));
00730 
00731         if (!access(tt_file, R_OK)) {
00732 
00733             if (later_date(filename, tt_file) &&
00734                 cifconv_type(tt_file) == 1) {
00735                 return(tt_file);
00736             }
00737         }
00738     }
00739 
00740 
00741 
00742     /* 2. see if CIFDIR is set */
00743 
00744     value = getenv("CIFDIR");
00745     if (value != (char *) NULL) {
00746         cifdir = value;
00747 
00748         cifdir_file = (char *) malloc(sizeof(char) *
00749                                       (strlen(cifdir) + 
00750                                        strlen(cif_basename(filename)) +
00751                                        3));
00752 
00753         (void) sprintf(cifdir_file, "%s/%sT", cifdir, cif_basename(filename));
00754 
00755         if (!access(cifdir_file, R_OK)) {
00756 
00757             if (later_date(filename, cifdir_file) &&
00758                 cifconv_type(cifdir_file) == 1) {
00759 
00760                 if (tt_file != (char *) NULL)
00761                     free(tt_file);
00762 
00763                 return(cifdir_file);
00764             }
00765         }
00766     }
00767 
00768     /* 3. See if the cifconv cif exists next to the original cif */
00769 
00770     outfile = (char *) malloc(sizeof(char) *
00771                               (strlen(filename) + 2));
00772     (void) sprintf(outfile, "%sT", filename);
00773 
00774     if (!access(outfile, R_OK)) {
00775 
00776         if (later_date(filename, outfile) &&
00777             cifconv_type(outfile) == 1) {
00778 
00779             if (tt_file != (char *) NULL)
00780                 free(tt_file);
00781 
00782             if (cifdir_file != (char *) NULL)
00783                 free(cifdir_file);
00784 
00785             return(outfile);
00786         }
00787     }
00788 
00789 
00790 
00791     /* Cifconv does not exist already, so we have to create it */
00792 
00793     /* Only want to create the cif in none-tmp space if keep == True */
00794     if (keep == 1) {
00795 
00796         /*
00797          * 4. See if we need to write into the tt_directory, only used
00798          * by xbrowse through an unpublished function cif_convdir(dir).
00799          */
00800 
00801         if (tt_file != (char *) NULL &&
00802             cif_VerifyCanWrite(tt_file)) {
00803 
00804             create_cif_file = strdup(tt_file);
00805         }
00806         else
00807 
00808         /* 4. See if we can write to CIFDIR */
00809 
00810         if (cifdir_file != (char *) NULL &&
00811             cif_VerifyCanWrite(cifdir_file)) {
00812 
00813             create_cif_file = strdup(cifdir_file);
00814         }
00815         else
00816 
00817             /* 5. See if we can write next to the original file */
00818 
00819             if (outfile != (char *) NULL &&
00820                 cif_VerifyCanWrite(outfile)) {
00821 
00822                 create_cif_file = strdup(outfile);
00823             }
00824     }
00825 
00826     if (create_cif_file == (char *) NULL) {
00827 
00828         /* 6. put the cif into /tmp, see of TMPDIR is available */
00829 
00830         value = getenv("TMPDIR");
00831         if (value != (char *) NULL && assertCanWriteDir(value) == 1) {
00832             tmpdir = value;
00833         }
00834         else {
00835 
00836             create_cif_file = (char *) malloc(sizeof(char) *
00837                                               (strlen("/tmp/") + 
00838                                                strlen(cif_basename(filename)) +
00839                                                7));
00840 
00841             /* 7. else create a tmp, tmp directory */
00842             (void) sprintf(create_cif_file, "/tmp/%sXXXXXX", cif_basename(filename));
00843             (void) mktemp(create_cif_file);
00844         }
00845 
00846         if (create_cif_file == (char *) NULL) {
00847             create_cif_file = (char *) malloc(sizeof(char) *
00848                                               (strlen(tmpdir) + 
00849                                                strlen(cif_basename(filename)) +
00850                                                3));
00851 
00852             (void) sprintf(create_cif_file, "%s/%sT", tmpdir, cif_basename(filename));
00853         }
00854 
00855         /*
00856          * indicate that a tmp cif file is about to be created; it will
00857          * be removed on cif_close
00858          */
00859 
00860         *tmp_cif = 1;
00861 
00862     }
00863 
00864     create_cif_file = Cif_Make_Cifconv(filename, create_cif_file, rtypes);
00865 
00866     /* free up allocated strings */
00867 
00868     if (cifdir_file != (char *) NULL) (void) free(cifdir_file);
00869     if (tt_file != (char *) NULL) (void) free(tt_file);
00870     if (outfile != (char *) NULL) (void) free(outfile);
00871 
00872     return(create_cif_file);
00873 }
00874 
00875 
00876 int Cif_Cifconv
00877 #ifdef __STDC__
00878 (char *filename, char *optype, int *rtypes, int version, int keep)
00879 #else
00880 (filename, optype, rtypes, version, keep)
00881 char *filename;                 /* file name */
00882 char *optype;                   /* open type */
00883 int *rtypes;                    /* ptr to array of selected record types */
00884 int version;                    /* CIF version expected by tools */
00885 int keep;                       /* keep the file on exit ? */
00886 #endif
00887 {
00888 
00889     char *cif_name;
00890     int tmp_cif;  /*
00891                    * set by cif_convert_to_cifconv if a tmp file has been
00892                    * created to hold the cifconv cif; the cif should be deleted
00893                    * by cif_close
00894                    */
00895     int ret;
00896 
00897     if (_cif_version == 0)
00898         _cif_version = 1;
00899 
00900     /*
00901      * If keep & 0x100 this is a hidden flag to say that cifconv should
00902      * report on any inconsistencies it finds in the cif to stderr
00903      */
00904 
00905     if (keep & 0x100) {
00906         global_error_report = True;
00907     }
00908 
00909     /*
00910      * If this is the first time through, we must initialize some
00911      * data structures
00912      */
00913 
00914     if (first_time == True) {
00915         sid.tbl = (long *) NULL;
00916         sid.max = 0;
00917         sid.cur = 0;
00918 #ifdef REMAP_FID
00919         fid.tbl = (long *) NULL;
00920         fid.max = 0;
00921         fid.cur = 0;
00922 #endif
00923         first_time = False;
00924     }
00925 
00926     /* convert filename to cif_cifconv name */
00927     cif_name = cif_convert_to_cifconv(filename, keep & 0xff, &tmp_cif, rtypes);
00928 
00929     /* an empty filename means that the cif is invalid or not there */
00930     if (cif_name == (char *) NULL) {
00931         return(cifconv_return_code);
00932     }
00933 
00934     /* open the file and return */
00935 
00936     if (version == 2) {
00937         ret = Cif_Open_V2(cif_name, optype, rtypes, version);
00938     }
00939     else {
00940         ret = Cif_Open_V3_1(cif_name, optype, rtypes, version, 
00941                             CIF_SUB_VERSION_3);
00942     }
00943 
00944     /*
00945      * If a valid open, set the tmp_cif flag according to indicate if a
00946      * temporary file has been created that should be removed on cif_close
00947      */
00948 
00949     if (ret >= 0) {
00950         _Cif_filetbl[ret].tmp_cif = tmp_cif;
00951     }
00952 
00953     /* free up the converted filename, cif_open will have take a copy */
00954 
00955     free(cif_name);
00956 
00957     /* Return whatever cif_open returned */
00958 
00959     return(ret);
00960 }
00961 
00962 
00963 /*
00964  * As above + added a check to see of the cif.h in use matches what this
00965  * library was compiled with...looks at CIF_SUB_VERSION_2 which must match
00966  * the sub_version passed. See cif_open macros in cif.h for more details.
00967  */
00968 
00969 int Cif_Cifconv_V2_1
00970 #ifdef __STDC__
00971 (char *filename, char *optype, int *rtypes, int version, int keep, int sub_version)
00972 #else
00973 (filename, optype, rtypes, version, keep, sub_version)
00974 char *filename;                 /* file name */
00975 char *optype;                   /* open type */
00976 int *rtypes;                    /* ptr to array of selected record types */
00977 int version;                    /* CIF version expected by tools */
00978 int keep;                       /* keep the file on exit ? */
00979 int sub_version;                /* version number of the cif.h */
00980 #endif
00981 {
00982 
00983     _cif_version = 2;
00984     if (sub_version != CIF_SUB_VERSION_2)
00985         return(CIF_SUBVER);
00986 
00987     return(Cif_Cifconv(filename, optype, rtypes,
00988                        version, keep));
00989 }
00990 
00991 /*
00992  * As above for version 3
00993  */
00994 
00995 int Cif_Cifconv_V3_1
00996 #ifdef __STDC__
00997 (char *filename, char *optype, int *rtypes, int version, int keep, int sub_version)
00998 #else
00999 (filename, optype, rtypes, version, keep, sub_version)
01000 char *filename;                 /* file name */
01001 char *optype;                   /* open type */
01002 int *rtypes;                    /* ptr to array of selected record types */
01003 int version;                    /* CIF version expected by tools */
01004 int keep;                       /* keep the file on exit ? */
01005 int sub_version;                /* version number of the cif.h */
01006 #endif
01007 {
01008     _cif_version = 3;
01009     if (sub_version != CIF_SUB_VERSION_3)
01010         return(CIF_SUBVER);
01011 
01012     return(Cif_Cifconv(filename, optype, rtypes,
01013                        version, keep));
01014 }
01015 
01016 
01017 /*
01018  * Duplicate a cif record, noting the new new one so that it can be
01019  * freed later to avoid memory leaks.
01020  */
01021 
01022 static struct Cif_generic **record_store = (struct Cif_generic **) NULL;
01023 static int current_store_record = 0;
01024 static int max_store_record = 0;
01025 
01026 static struct Cif_generic *cif_copy_record(struct Cif_generic *cifp)
01027 {
01028     struct Cif_generic *return_cifp = Cif_Duplicate(cifp);
01029 
01030     if (current_store_record == max_store_record) {
01031         max_store_record+=200;
01032         if (record_store == (struct Cif_generic **) NULL)
01033             record_store = (struct Cif_generic **)
01034                 malloc(max_store_record * sizeof(struct Cif_generic *));
01035         else
01036             record_store = (struct Cif_generic **)
01037                 realloc(record_store,
01038                         max_store_record * sizeof(struct Cif_generic *));
01039 
01040     }
01041 
01042     record_store[current_store_record++] = return_cifp;
01043     return(return_cifp);
01044 }
01045 
01046 
01047 /* Free up all of the space attached to copied records */
01048 static void free_copied_blocks()
01049 {
01050     int i;
01051 
01052     for (i = 0; i < current_store_record; i++) {
01053         Cif_Free(record_store[i]);
01054     }
01055     current_store_record = 0;
01056 }
01057 
01058 
01059 
01060 /* ------------------------------------------------------------------------
01061  * sortfile reorganizes the file into sorted order and adds the directory
01062  * records.
01063  * ------------------------------------------------------------------------
01064  */
01065 
01066 static int sortfile (
01067         struct Cif_generic *cifp)                       /* pointer to input cif header structure */
01068 {
01069 
01070         int i, rtype;
01071         int unit_found = 0;                             /* previous unit encountered flag */
01072         struct Cif_generic *fdp;                /* pointer to file directory */
01073         struct Cif_generic *cifp1;              /* cif record pointer */
01074         long sid;
01075         struct Cif_urectbl *urp;
01076         int in_unit = 0;                        /* not currently processing
01077                                                  * a unit */
01078 
01079         /* Test the output file for ability to position */
01080 
01081         if (Cif_Getpos (outfd) >= 0)
01082                 canpos = True;
01083 
01084         /* Add header structure to pointer array.  Create the unit directory table.
01085          * Read each record and process.
01086          */
01087 
01088         CIFHDR(cifp)->form = CIF_FORM_SORTED;
01089         /*
01090          * We are writing a cifconv mode binary file, so set the bintype
01091          * to show that cifconv wrote this cif file
01092          */
01093 
01094         CIFHDR(cifp)->bintype = CIF_FORM_CIFCONV;
01095 
01096         /* Make sure that the record structures are all empty */
01097         for (i = 0; i < CIF_MAXRECORD; i++) {
01098             patbl[i].aptr = NULL;
01099             patbl[i].psize = 0;
01100             patbl[i].next = (int)NULL;
01101         }
01102 
01103         if ((cifp1 = cif_copy_record(cifp)) == NULL)
01104                 MEM_ERROR;
01105         addstruct (cifp1);
01106         while ((rtype = Cif_Getrecord (infd, &cifp)) >= 0) {
01107                 if (rtype == CIF_UNIT) {
01108 
01109                     in_unit = 1;
01110 
01111                         /* If one previous unit encountered, create the scratch file.  If
01112                          * any previous units found, write the unit to the scratch file,
01113                          * release the memory used for the previous unit and clear the patbl
01114                          * arrays for unit records.  Add the unit record.
01115                          */
01116 
01117                         if ((cifp = cif_copy_record (cifp)) == NULL) MEM_ERROR;
01118                         if (unit_found == 1) {
01119                                 tfile = tempnam (NULL, "cif.");
01120                                 if ((tmpfd = Cif_Open (tfile, "w", NULL, CIF_VERSION)) < 0) {
01121                                         (void) fprintf (stderr, "libcif: cannot create temporary file %s - %s\n",
01122                                                 tfile, Cif_Errstring(tmpfd));
01123                                         return (tmpfd);
01124                                 }
01125                         }
01126                         if (unit_found > 0) {
01127                                 if ((i = write_unit (tmpfd, False, True)) < 0)
01128                                         return (i);
01129                                 (void) Cif_Release (infd, CIF_MEM_KEEP);
01130                                 for (i = 0; i < CIF_MAXRECORD; i++)
01131                                         if (unit_record[i]) patbl[i].next = 0;
01132                         }
01133                         unit_found++;
01134                         addstruct (cifp);
01135                         addunit(cifp);
01136                         makeudir();
01137                 }
01138 
01139                 else if (rtype == CIF_ENDUNIT) {
01140 
01141                         addstruct (cifp);
01142                         cifp1 = *(patbl[CIF_UNITDIR].aptr);
01143                         urp = CIFUDIR(cifp1)->ur;
01144                         for (i = 0; i < CIF_MAXRECORD; i++) {
01145                                 if (unit_record[i])
01146                                         urp[i].nrecords = patbl[i].next;
01147                         }
01148 
01149                         in_unit = 0;
01150                 }
01151 
01152                 else if (unit_record[rtype])
01153                         addstruct (cifp);
01154 
01155                 else {
01156 
01157                         /* Copy the record to new space so it will survive a call to
01158                          * Cif_Release and add to the record list.
01159                          */
01160 
01161                         if ((cifp1 = cif_copy_record (cifp)) == NULL)
01162                                 MEM_ERROR;
01163                         addstruct (cifp1);
01164                 }
01165 
01166         }
01167         if (rtype != CIF_EOF) {
01168                 (void) fprintf (stderr, "libcif: error reading input file - %s\n",
01169                          Cif_Errstring(rtype));
01170                 return (rtype);
01171         }
01172 
01173         /*
01174          * If we have hit EOF without the endunit, something has gone
01175          * wrong, so flush the unit
01176          */
01177         if (in_unit == 1) {
01178             struct Cif_urectbl *urp;
01179 
01180             addstruct (cifp);
01181             cifp1 = *(patbl[CIF_UNITDIR].aptr);
01182             urp = CIFUDIR(cifp1)->ur;
01183             for (i = 0; i < CIF_MAXRECORD; i++) {
01184                 if (unit_record[i])
01185                     urp[i].nrecords = patbl[i].next;
01186             }
01187         }
01188 
01189         /* If more than one unit, copy last unit to scratch file.  */
01190 
01191         if (unit_found > 1) {
01192                 if ((i = write_unit (tmpfd, False, True)) < 0)
01193                         return (i);
01194         }
01195 
01196         /* Remap the file ids if needed then determine and save the values for
01197          * the file directory.
01198          */
01199 
01200 #ifdef REMAP_FID
01201         if (Remap_id == True)
01202                 remap_files ();
01203 #endif
01204 
01205         /* If the file directory doesn't exist, create it and the unit table */
01206 
01207         if (patbl[CIF_FILEDIR].aptr == NULL) {
01208                 if ((fdp = (struct Cif_generic *) malloc (sizeof(struct Cif_filedir)))
01209                         == NULL) MEM_ERROR;
01210                 (void) memset ((char *)fdp, '\0', sizeof(struct Cif_filedir));
01211                 CIFFDIR(fdp)->rectype = CIF_FILEDIR;
01212                 CIFFDIR(fdp)->nunits = 0;
01213                 addstruct (fdp);
01214         }
01215 
01216         cifp1 = *(patbl[CIF_FILEDIR].aptr);
01217         CIFFDIR(cifp1)->maxfid = get_max_fid ();
01218         CIFFDIR(cifp1)->nfiles = patbl[CIF_FILE].next;
01219         CIFFDIR(cifp1)->nincs = patbl[CIF_INCLUDE].next;
01220 
01221         /* Write out the header.  If a single unit, write it from patbl.  If
01222          * multiple units, copy 'em from the scratch file.
01223          */
01224         
01225         if (unit_found == 1) {
01226                 if (Remap_id == True)
01227                         remap_symbols();
01228                 sid = get_max_sid ();
01229                 cifp1 = *(patbl[CIF_UNITDIR].aptr);
01230                 CIFUDIR(cifp1)->maxsid = sid;
01231                 cifp1 = *(patbl[CIF_FILEDIR].aptr);
01232                 CIFFDIR(cifp1)->maxsid = sid;
01233         }
01234         if (write_header() != 0)
01235                 return(1);
01236 
01237         /* If no units found, something has gone wring */
01238         if (unit_found == 0 &&
01239             in_unit == 0)
01240             return(-1);
01241 
01242         if (unit_found == 1) {
01243                 if ((i = write_unit(outfd, canpos, True)) < 0)
01244                         return (i);
01245         }
01246         else {
01247             if (unit_found >= 1) {
01248                 if (copy_units () != 0)
01249                     return (1);
01250             }
01251         }
01252 
01253         if (canpos == True) {
01254                 if ((i = Cif_Setpos (outfd, fdirpos)) < 0)
01255                         OUT_ERROR ("positioning", outfd, i);
01256                 cifp1 = *(patbl[CIF_FILEDIR].aptr);
01257                 if ((i = Cif_Putrecord (outfd, cifp1)) < 0)
01258                         OUT_ERROR ("writing", outfd, i);
01259         }
01260 
01261         /* Free up the memory */
01262         for (i = 0; i < CIF_MAXRECORD; i++) {
01263 
01264             if (patbl[i].aptr != (struct Cif_generic **) NULL) {
01265 
01266                 if (i == CIF_FILEDIR) {
01267                     if (CIFFDIR(patbl[i].aptr[0])->ut !=
01268                         (struct Cif_unittbl *) NULL)
01269                         (void) free(CIFFDIR(patbl[i].aptr[0])->ut);
01270 
01271                     (void) free(CIFFDIR(patbl[i].aptr[0]));
01272                 }
01273                 (void) free(patbl[i].aptr);
01274                 patbl[i].aptr = (struct Cif_generic **) NULL;
01275             }
01276             patbl[i].psize = 0;
01277             patbl[i].next = (int)NULL;
01278         }
01279 
01280         return (0);
01281 
01282 }
01283 
01284 /* --------------------------------------------------------------------------
01285  * addstruct adds one structure to the appropriate pointer array in patbl.
01286  * --------------------------------------------------------------------------
01287  */
01288 
01289 static void addstruct (
01290         struct Cif_generic *cifp)               /* pointer to CIF structure */
01291 {
01292         static int last_line = 0; /* stores the last position of a stmt record */
01293         static int last_cpos = 0; /* stmt's at the same position need to get
01294                                    * an extra marker showing their relative
01295                                    * line positions as qsort is not
01296                                    * guaranteed to preserve "like" records
01297                                    * the rectype field is used for this purpose;
01298                                    * which we ensure is reset after the sort.
01299                                    */
01300         static int last_position = 0; /* order for records at some position */
01301 
01302         register int i, rtype;
01303 
01304         rtype = cifp->rectype;
01305         if ((lang == CIF_LG_C || lang == CIF_LG_CC) && rtype == CIF_STMT_TYPE) {
01306                 if (CIFSTMT(cifp)->line == last_line &&
01307                     CIFSTMT(cifp)->cpos == last_cpos) {
01308                         last_position++;
01309                         cifp->rectype = last_position;
01310                                 /* this is really bad, but we can get away with
01311                                  * it because; a) rectype will be reset,
01312                                  *             b) it is not needed for now
01313                                  * and         c) we can't increase the record
01314                                  *               size to do it correctly for
01315                                  *               users already use this struct
01316                                  */
01317                 } 
01318                 else {
01319                         last_line = CIFSTMT(cifp)->line;
01320                         last_cpos = CIFSTMT(cifp)->cpos;
01321                         last_position = 0;
01322                         cifp->rectype = 0;
01323                 }
01324 
01325         }
01326         if (patbl[rtype].aptr == NULL) {
01327                 patbl[rtype].psize = pabump[rtype];
01328                 if ((patbl[rtype].aptr = (struct Cif_generic **) malloc (
01329                                 sizeof(struct Cif_generic *) * patbl[rtype].psize)) == NULL)
01330                 {
01331                         MEM_ERROR;
01332                 }
01333         }
01334         i = patbl[rtype].next++;
01335         if ((i) >= patbl[rtype].psize) {
01336                 patbl[rtype].psize += pabump[rtype];
01337 
01338                 if ((patbl[rtype].aptr = (struct Cif_generic **) realloc (
01339                                 (char *)patbl[rtype].aptr,
01340                                 sizeof(struct Cif_generic *)*patbl[rtype].psize)) == NULL)
01341                 {
01342                         MEM_ERROR;
01343                 }
01344         }
01345         (patbl[rtype].aptr)[i] = cifp;
01346 }
01347 
01348 
01349 /* --------------------------------------------------------------------------
01350  * addunit adds another unit to the file directory.  If the file directory
01351  * doesn't exit, it's created first.
01352  * --------------------------------------------------------------------------
01353  */
01354 
01355 static void addunit (
01356         struct Cif_generic *unitp)              /* pointer to unit record structure */
01357 {
01358 
01359 #       define UTBUMP 100                               /* Increment size for unit table */
01360         static int utsize = 0;          /* current allocated size of unit table */
01361 
01362         int i;
01363         struct Cif_generic *fdp;                /* pointer to file directory */
01364         struct Cif_unittbl *ut;                 /* pointer to unit table */
01365 
01366         /* If the file directory doesn't exist, create it and the unit table */
01367 
01368         if (patbl[CIF_FILEDIR].aptr == NULL) {
01369                 if ((fdp = (struct Cif_generic *) malloc (sizeof(struct Cif_filedir)))
01370                         == NULL) MEM_ERROR;
01371                 (void) memset ((char *)fdp, '\0', sizeof(struct Cif_filedir));
01372                 CIFFDIR(fdp)->rectype = CIF_FILEDIR;
01373                 CIFFDIR(fdp)->nunits = 0;
01374                 utsize = UTBUMP;
01375                 if ((ut = CIFFDIR(fdp)->ut = (struct Cif_unittbl *) malloc
01376                         (sizeof(struct Cif_unittbl)*utsize)) == NULL) MEM_ERROR;
01377                 addstruct (fdp);
01378         }
01379 
01380         /* If the unit table is full, increase the size. */
01381 
01382         fdp = *(patbl[CIF_FILEDIR].aptr);
01383         if ((int) CIFFDIR(fdp)->nunits >= utsize) {
01384                 utsize += UTBUMP;
01385                 if ((ut = CIFFDIR(fdp)->ut = (struct Cif_unittbl *) realloc (
01386                                 (char *) CIFFDIR(fdp)->ut,
01387                                 sizeof(struct Cif_unittbl)*utsize)) == NULL) MEM_ERROR;
01388 
01389         }
01390 
01391         /* add the unit to the unit table */
01392 
01393         i = CIFFDIR(fdp)->nunits++;
01394         ut = CIFFDIR(fdp)->ut;
01395         (void) memset((char *)&ut[i], 0, sizeof(struct Cif_unittbl));
01396         ut[i].name = /* strdup( */ CIFUNIT(unitp)->name /* ) */;
01397         ut[i].nlen = strlen(ut[i].name);
01398         ut[i].unitpos = 0;
01399 
01400 }
01401 
01402 /* --------------------------------------------------------------------------
01403  * The various record compare routines compare two CIF structures for sorting
01404  * by qsort.  Structures are sorted as follows:
01405  *
01406  * CIF_CALLSITE         comp_callsite           by symbol id, file, line, and column
01407  * CIF_COMBLK           comp_comblk             by symbol id
01408  * CIF_CONST            comp_const              by symbol id
01409  * CIF_ENTRY            comp_entry              by symbol id
01410  * CIF_FILE             comp_file               by file id
01411  * CIF_LABEL            comp_label              by symbol id
01412  * CIF_LOOP             comp_label              by file, line, and column
01413  * CIF_MESSAGE          comp_message            by file, line, and column
01414  * CIF_NAMELIST         comp_namelist           by symbol id
01415  * CIF_OBJECT           comp_object             by symbol id
01416  * CIF_STMT_TYPE        comp_stmt_type          by file, line, and column
01417  * CIF_USAGE            comp_usage              by symbol id
01418  * CIF_CDIR             comp_cdir               by file, line and column
01419  * CIF_CDIR_DOSHARED    comp_cdir_doshared      by file, line and column
01420  # CIF_GEOMETRY         comp_geometry           by geometry id
01421  * CIF_CONTINUATION     comp_continuation       by file, line and column
01422  * CIF_TRANSFORM        comp_transform          by file and line
01423  * CIF_C_TAG            comp_c_tag              by symbol id
01424  * CIF_C_MESSAGE        comp_c_message          by file, line
01425  * CIF_C_CONST          comp_c_const            by symbol id
01426  * CIF_C_ENTRY          comp_c_entry            by symbol id
01427  * CIF_C_OBJECT         comp_c_object           by symbol id
01428  * CIF_C_LINT_DIRECTIVE comp_c_lint_directive   by object id
01429  * CIF_C_MACRO_DEF      comp_c_macro_def        by macro id
01430  * CIF_C_MACRO_UNDEF    comp_c_macro_undef      by macro id
01431  * CIF_C_MACRO_USAGE    comp_c_macro_usage      by macro id
01432  * CIF_C_ENTRY_END      comp_c_entry_end        by symbol id
01433  * CIF_F90_CALLSITE     comp_f90_callsite,      by symbol id, file, line, and column
01434  * CIF_F90_COMBLK       comp_f90_comblk,        by symbol id
01435  * CIF_F90_CONST        comp_f90_const,         by symbol id
01436  * CIF_F90_ENTRY        comp_f90_entry,         by symbol id
01437  * CIF_F90_LOOP         comp_f90_loop,          by file, line, and column
01438  * CIF_F90_DERIVED_TYPE comp_f90_derived_type,  by symbol id
01439  * CIF_F90_LABEL        comp_f90_label,         by file, line, and colum
01440  * CIF_F90_NAMELIST     comp_f90_namelist,      by symbol id
01441  * CIF_F90_OBJECT       comp_f90_object,        by symbol id
01442  * CIF_F90_BEGIN_SCOPE  comp_f90_begin_scope,   by scope id
01443  * CIF_F90_END_SCOPE    comp_f90_end_scope,     by scope id
01444  * CIF_F90_SCOPE_INFO   comp_f90_scope_info,    by scope id
01445  * CIF_F90_USE_MODULE   comp_f90_use_module,    by symbol id
01446  * CIF_F90_RENAME       comp_f90_rename,        by symbol id
01447  * CIF_F90_INT_BLOCK    comp_f90_int_block,     by scope id
01448  * CIF_F90_VECTORIZATION comp_f90_vectorization, ??
01449  * CIF_CC_TYPE          comp_cc_type,           by type id
01450  * CIF_CC_ENTRY         comp_cc_entry,          by symbol id
01451  * CIF_CC_OBJ           comp_cc_obj,            by symbol id
01452  * CIF_CC_SUBTYPE       comp_cc_subtype,        by symbol id
01453  * CIF_CC_ENUM          comp_cc_enum,           by symbol id
01454  * CIF_CC_EXPR          comp_cc_expr,           by expression id
01455  * --------------------------------------------------------------------------
01456  */
01457 
01458 static int comp_callsite (
01459         struct Cif_callsite **p1,
01460         struct Cif_callsite **p2)
01461 {
01462         register int ret;
01463 
01464         if ((ret = ( (*p1)->entryid - (*p2)->entryid )) != 0)
01465             return (ret);
01466         else if ((ret = ( (*p1)->fid - (*p2)->fid )) != 0)
01467                 return (ret);
01468         else if ((ret = ( (*p1)->line - (*p2)->line )) != 0)
01469                 return (ret);
01470         else
01471                 return ( (*p1)->cpos - (*p2)->cpos );
01472 }
01473 
01474 static int comp_comblk (
01475         struct Cif_comblk **p1, 
01476         struct Cif_comblk **p2)
01477 {
01478         return ( (*p1)->symid - (*p2)->symid );
01479 }
01480 
01481 static int comp_const (
01482         struct Cif_const **p1,
01483         struct Cif_const **p2)
01484 {
01485         return ( (*p1)->symid - (*p2)->symid );
01486 }
01487 
01488 static int comp_entry (
01489         struct Cif_entry **p1,
01490         struct Cif_entry **p2)
01491 {
01492         return ( (*p1)->symid - (*p2)->symid );
01493 }
01494 
01495 static int comp_file (
01496         struct Cif_file **p1,
01497         struct Cif_file **p2)
01498 {
01499         return ( (*p1)->fid - (*p2)->fid );
01500 }
01501 
01502 static int comp_label (
01503         struct Cif_label **p1,
01504         struct Cif_label **p2)
01505 {
01506         return ( (*p1)->symid - (*p2)->symid );
01507 }
01508 
01509 static int comp_loop (
01510         struct Cif_loop **p1,
01511         struct Cif_loop **p2)
01512 {
01513         register int ret;
01514 
01515         if ((ret = ( (*p1)->sfid - (*p2)->sfid )) != 0)
01516                 return (ret);
01517         else if ((ret = ( (*p1)->strline - (*p2)->strline )) != 0)
01518                 return (ret);
01519         else
01520                 return ( (*p1)->strcpos - (*p2)->strcpos );
01521 }
01522 
01523 static int comp_message (
01524         struct Cif_message **p1,
01525         struct Cif_message **p2)
01526 {
01527         register int ret;
01528 
01529         if ((ret = ( (*p1)->fid - (*p2)->fid )) != 0)
01530                 return (ret);
01531         else if ((ret = ( (*p1)->fline - (*p2)->fline )) != 0)
01532                 return (ret);
01533         else
01534                 return ( (*p1)->cpos - (*p2)->cpos );
01535 }
01536 
01537 static int comp_namelist (
01538         struct Cif_namelist **p1,
01539         struct Cif_namelist **p2)
01540 {
01541         return ( (*p1)->symid - (*p2)->symid );
01542 }
01543 
01544 static int comp_object (
01545         struct Cif_object **p1,
01546         struct Cif_object **p2)
01547 {
01548         return ( (*p1)->symid - (*p2)->symid );
01549 }
01550 
01551 static int comp_stmt_type (
01552         struct Cif_stmt_type **p1,
01553         struct Cif_stmt_type **p2)
01554 {
01555         register int ret;
01556 
01557         if ((ret = ( (*p1)->fid - (*p2)->fid )) != 0)
01558                 return (ret);
01559         else if ((ret = ( (*p1)->line - (*p2)->line )) != 0)
01560                 return (ret);
01561         else if (lang == CIF_LG_F90 && _cif_version >= 3) {
01562           /* F90 V3 has introduced a statement ordering field which
01563            * is stored in the eline field - otherwise unused for f90 - 
01564            * this orders statements on the same line as the cpos is
01565            * not guaranteed.
01566            */
01567           if ((ret = ( (*p1)->eline - (*p2)->eline )) != 0)
01568             return(ret);
01569           else
01570              return((*p1)->cpos - (*p2)->cpos);
01571         }
01572         else if ((ret = ( (*p1)->cpos - (*p2)->cpos )) != 0)
01573                 return(ret);
01574         else /* rectype will contain indicator of original ordering */
01575                 return((*p1)->rectype - (*p2)->rectype);
01576 }
01577 
01578 
01579 static int comp_usage (
01580         struct Cif_usage **p1,
01581         struct Cif_usage **p2)
01582 {
01583     register int ret;
01584     register int i;
01585 
01586     if ((ret = ( (*p1)->symid - (*p2)->symid )) != 0)
01587         return (ret);
01588     else/* sort on # member id's, if any */
01589         if ((ret = ( (*p1)->nmembs - (*p2)->nmembs)) != 0)
01590             return (ret);
01591         else
01592             if ((*p1)->nmembs == 0)
01593                 return(0);
01594             else { /* sort on each member id in turn */
01595                 for (i = 0; i < (int) (*p1)->nmembs; i++) {
01596                     if ((ret = ( (*p1)->membs[i] - (*p2)->membs[i] )) != 0)
01597                         return (ret);
01598                 }
01599             }
01600 
01601     return(0);
01602 }
01603 
01604 
01605 
01606 #ifndef CRAY2
01607 static int comp_f90_callsite (
01608         struct Cif_f90_callsite **p1,
01609         struct Cif_f90_callsite **p2)
01610 {
01611         register int ret;
01612 
01613         if ((ret = ( (*p1)->entryid - (*p2)->entryid )) != 0)
01614                 return (ret);
01615         else if ((ret = ( (*p1)->fid - (*p2)->fid )) != 0)
01616                 return (ret);
01617         else if ((ret = ( (*p1)->line - (*p2)->line )) != 0)
01618                 return (ret);
01619         else
01620                 return ( (*p1)->cpos - (*p2)->cpos );
01621 }
01622 
01623 static int comp_f90_comblk (
01624         struct Cif_f90_comblk **p1, 
01625         struct Cif_f90_comblk **p2)
01626 {
01627         return ( (*p1)->symid - (*p2)->symid );
01628 }
01629 
01630 static int comp_f90_const (
01631         struct Cif_f90_const **p1,
01632         struct Cif_f90_const **p2)
01633 {
01634         return ( (*p1)->symid - (*p2)->symid );
01635 }
01636 
01637 static int comp_f90_entry (
01638         struct Cif_f90_entry **p1,
01639         struct Cif_f90_entry **p2)
01640 {
01641         return ( (*p1)->symid - (*p2)->symid );
01642 }
01643 
01644 
01645 static int comp_f90_label (
01646         struct Cif_f90_label **p1,
01647         struct Cif_f90_label **p2)
01648 {
01649         return ( (*p1)->symid - (*p2)->symid );
01650 }
01651 
01652 static int comp_f90_loop (
01653         struct Cif_f90_loop **p1,
01654         struct Cif_f90_loop **p2)
01655 {
01656         register int ret;
01657 
01658         if ((ret = ( (*p1)->sfid - (*p2)->sfid )) != 0)
01659                 return (ret);
01660         else if ((ret = ( (*p1)->strline - (*p2)->strline )) != 0)
01661                 return (ret);
01662         else
01663                 return ( (*p1)->strcpos - (*p2)->strcpos );
01664 }
01665 
01666 static int comp_f90_namelist (
01667         struct Cif_f90_namelist **p1,
01668         struct Cif_f90_namelist **p2)
01669 {
01670         return ( (*p1)->symid - (*p2)->symid );
01671 }
01672 
01673 static int comp_f90_object (
01674         struct Cif_f90_object **p1,
01675         struct Cif_f90_object **p2)
01676 {
01677         return ( (*p1)->symid - (*p2)->symid );
01678 }
01679 
01680 static int comp_f90_derived_type (
01681         struct Cif_f90_derived_type **p1,
01682         struct Cif_f90_derived_type **p2)
01683 {
01684         return ( (*p1)->symid - (*p2)->symid );
01685 }
01686 
01687 static int comp_f90_begin_scope (
01688         struct Cif_f90_begin_scope **p1,
01689         struct Cif_f90_begin_scope **p2)
01690 {
01691         return ( (*p1)->scopeid - (*p2)->scopeid );
01692 }
01693 
01694 static int comp_f90_end_scope (
01695         struct Cif_f90_end_scope **p1,
01696         struct Cif_f90_end_scope **p2)
01697 {
01698         return ( (*p1)->scopeid - (*p2)->scopeid );
01699 }
01700 
01701 static int comp_f90_scope_info (
01702         struct Cif_f90_scope_info **p1,
01703         struct Cif_f90_scope_info **p2)
01704 {
01705         return ( (*p1)->scopeid - (*p2)->scopeid );
01706 }
01707 
01708 static int comp_f90_int_block (
01709         struct Cif_f90_int_block **p1,
01710         struct Cif_f90_int_block **p2)
01711 {
01712         return ( (*p1)->intid - (*p2)->intid );
01713 }
01714 
01715 static int comp_f90_use_module (
01716         struct Cif_f90_use_module **p1,
01717         struct Cif_f90_use_module **p2)
01718 {
01719         return ( (*p1)->modid - (*p2)->modid );
01720 }
01721 
01722 static int comp_f90_rename (
01723         struct Cif_f90_rename **p1,
01724         struct Cif_f90_rename **p2)
01725 {
01726         return ( (*p1)->modid - (*p2)->modid );
01727 }
01728 
01729 static int comp_f90_vectorization (
01730         struct Cif_f90_vectorization **p1,
01731         struct Cif_f90_vectorization **p2)
01732 {
01733         return ( (*p1)->rectype - (*p2)->rectype );
01734 }
01735 #endif /* CRAY2 */
01736 
01737 
01738 static int comp_cdir (
01739         struct Cif_cdir **p1,
01740         struct Cif_cdir **p2)
01741 {
01742         register int ret;
01743 
01744         if ((ret = ( (*p1)->fid - (*p2)->fid )) != 0)
01745                 return (ret);
01746         else if ((ret = ( (*p1)->line - (*p2)->line )) != 0)
01747                 return (ret);
01748         else
01749                 return ( (*p1)->cpos - (*p2)->cpos );
01750 }
01751 
01752 static int comp_cdir_doshared (
01753         struct Cif_cdir_doshared **p1,
01754         struct Cif_cdir_doshared **p2)
01755 {
01756         register int ret;
01757 
01758         if ((ret = ( (*p1)->fid - (*p2)->fid )) != 0)
01759                 return (ret);
01760         else if ((ret = ( (*p1)->line - (*p2)->line )) != 0)
01761                 return (ret);
01762         else
01763                 return ( (*p1)->cpos - (*p2)->cpos );
01764 }
01765 
01766 
01767 static int comp_geometry (
01768         struct Cif_geometry **p1,
01769         struct Cif_geometry **p2)
01770 {
01771         return ( (*p1)->geomid - (*p2)->geomid );
01772 }
01773 
01774 
01775 static int comp_continuation (
01776         struct Cif_continuation **p1,
01777         struct Cif_continuation **p2)
01778 {
01779         register int ret;
01780 
01781         if ((ret = ( (*p1)->fid - (*p2)->fid )) != 0)
01782                 return (ret);
01783         else if ((ret = ( (*p1)->line - (*p2)->line )) != 0)
01784                 return (ret);
01785         else
01786                 return ( (*p1)->cpos - (*p2)->cpos );
01787 }
01788 
01789 static int comp_transform (
01790         struct Cif_transform **p1,
01791         struct Cif_transform **p2)
01792 {
01793         register int ret;
01794 
01795         if ((ret = ( (*p1)->fid - (*p2)->fid )) != 0)
01796                 return (ret);
01797         else
01798                 return ( (*p1)->line - (*p2)->line );
01799 }
01800 
01801 
01802 static int comp_c_tag (
01803         struct Cif_c_tag **p1,
01804         struct Cif_c_tag **p2)
01805 {
01806         return ( (*p1)->tagid - (*p2)->tagid );
01807 }
01808 
01809 static int comp_c_message (
01810         struct Cif_c_message **p1,
01811         struct Cif_c_message **p2)
01812 {
01813         register int ret;
01814 
01815         if ((ret = ( (*p1)->fline - (*p2)->fline )) != 0)
01816                 return (ret);
01817         else 
01818                 return ( (*p1)->iline - (*p2)->iline );
01819 }
01820 
01821 static int comp_c_const (
01822         struct Cif_c_const **p1,
01823         struct Cif_c_const **p2)
01824 {
01825         return ( (*p1)->symid - (*p2)->symid );
01826 }
01827 
01828 static int comp_c_entry (
01829         struct Cif_c_entry **p1,
01830         struct Cif_c_entry **p2)
01831 {
01832         return ( (*p1)->symid - (*p2)->symid );
01833 }
01834 
01835 static int comp_c_object (
01836         struct Cif_c_object **p1,
01837         struct Cif_c_object **p2)
01838 {
01839         return ( (*p1)->symid - (*p2)->symid );
01840 }
01841 
01842 static int comp_c_lint_directive (
01843         struct Cif_c_lint_directive **p1,
01844         struct Cif_c_lint_directive **p2)
01845 {
01846         return ( (*p1)->objid - (*p2)->objid );
01847 }
01848 
01849 static int comp_c_macro_def (
01850         struct Cif_c_macro_def **p1,
01851         struct Cif_c_macro_def **p2)
01852 {
01853         return ( (*p1)->symid - (*p2)->symid );
01854 }
01855 
01856 static int comp_c_macro_undef (
01857         struct Cif_c_macro_undef **p1,
01858         struct Cif_c_macro_undef **p2)
01859 {
01860         return ( (*p1)->symid - (*p2)->symid );
01861 }
01862 
01863 
01864 static int comp_c_macro_usage (
01865         struct Cif_c_macro_usage **p1,
01866         struct Cif_c_macro_usage **p2)
01867 {
01868         return ( (*p1)->symid - (*p2)->symid );
01869 }
01870 
01871 static int comp_c_entry_end (
01872         struct Cif_c_entry_end **p1,
01873         struct Cif_c_entry_end **p2)
01874 {
01875         return ( (*p1)->symid - (*p2)->symid );
01876 }
01877 
01878 static int comp_cc_type (
01879         struct Cif_cc_type **p1,
01880         struct Cif_cc_type **p2)
01881 {
01882         return ( (*p1)->typeId - (*p2)->typeId );
01883 }
01884 
01885 static int comp_cc_entry (
01886         struct Cif_cc_entry **p1,
01887         struct Cif_cc_entry **p2)
01888 {
01889         return ( (*p1)->symid - (*p2)->symid );
01890 }
01891 
01892 static int comp_cc_obj (
01893         struct Cif_cc_obj **p1,
01894         struct Cif_cc_obj **p2)
01895 {
01896         return ( (*p1)->symid - (*p2)->symid );
01897 }
01898 
01899 static int comp_cc_subtype (
01900         struct Cif_cc_subtype **p1,
01901         struct Cif_cc_subtype **p2)
01902 {
01903         return ( (*p1)->symid - (*p2)->symid );
01904 }
01905 
01906 static int comp_cc_enum (
01907         struct Cif_cc_enum **p1,
01908         struct Cif_cc_enum **p2)
01909 {
01910         return ( (*p1)->symid - (*p2)->symid );
01911 }
01912 
01913 static int comp_cc_expr (
01914         struct Cif_cc_expr **p1,
01915         struct Cif_cc_expr **p2)
01916 {
01917         return ( (*p1)->exprid - (*p2)->exprid );
01918 }
01919 
01920 static int comp_src_pos (
01921         struct Cif_src_pos **p1,
01922         struct Cif_src_pos **p2)
01923 {
01924         register int ret;
01925 
01926         if ((ret = ( (*p1)->kind - (*p2)->kind )) != 0)
01927                 return (ret);
01928         else if ((ret = ( (*p1)->fid - (*p2)->fid )) != 0)
01929                 return (ret);
01930         else
01931                 return ( (*p1)->symid - (*p2)->symid );
01932 }
01933 
01934 static int comp_orig_cmd (
01935         struct Cif_orig_cmd **p1,
01936         struct Cif_orig_cmd **p2)
01937 {
01938         return ( (*p1)->nlen - (*p2)->nlen );
01939 }
01940 
01941 
01942 
01943 
01944 /* --------------------------------------------------------------------------
01945  * copy_units copies all the units from the scratch file to the output file.
01946  * --------------------------------------------------------------------------
01947  */
01948 
01949 static int copy_units (
01950         void)
01951 {
01952 
01953         int recno=0;
01954         int i, rtype;
01955         long sid;
01956         struct Cif_generic *cifp;
01957 
01958         if (tmpfd != -1) {
01959             (void) Cif_Close (tmpfd, CIF_MEM_KEEP);
01960             tmpfd = -1;
01961         }
01962         if ((tmpfd = Cif_Open (tfile, "r", NULL, CIF_VERSION)) < 0) {
01963                 (void) fprintf (stderr, "libcif: cannot open temporary file %s - %s\n",
01964                                 tfile, Cif_Errstring(tmpfd));
01965                 return (tmpfd);
01966         }
01967         (void) Cif_Memmode (tmpfd, CIF_MEM_MANAGED);
01968 #ifndef DEBUG
01969         /* don't remove the temporary file in debug mode */
01970         (void) unlink (tfile);
01971 #endif
01972 
01973         while ((rtype = Cif_Getrecord (tmpfd, &cifp)) >= 0) {
01974 
01975                 recno++;
01976                 if (rtype == CIF_UNIT) {
01977                         for (i = 0; i < CIF_MAXRECORD; i++)
01978                                 if (unit_record[i]) patbl[i].next = 0;
01979                         addstruct (cifp);
01980                 }
01981 
01982                 else if (rtype == CIF_ENDUNIT) {
01983                         addstruct (cifp);
01984                         if (Remap_id == True)
01985                                 remap_symbols ();
01986                         sid = get_max_sid ();
01987                         cifp = *(patbl[CIF_UNITDIR].aptr);
01988                         CIFUDIR(cifp)->maxsid = sid;
01989                         cifp = *(patbl[CIF_FILEDIR].aptr);
01990                         if (sid > (int) CIFFDIR(cifp)->maxsid)
01991                                 CIFFDIR(cifp)->maxsid = sid;
01992                         if ((i = write_unit (outfd, canpos, False)) < 0)
01993                                 return (i);
01994                         (void) Cif_Release (tmpfd, CIF_MEM_KEEP);
01995                 }
01996 
01997                 else
01998                         addstruct (cifp);
01999         }
02000         if (rtype != CIF_EOF)
02001                 OUT_ERROR ("reading", tmpfd, rtype);
02002 
02003         return (0);
02004 }
02005 
02006 /* --------------------------------------------------------------------------
02007  * makeudir creates a Cif_unitdir structure to contain entries for each type
02008  * of unit structure present.
02009  * --------------------------------------------------------------------------
02010  */
02011 
02012 static void makeudir(
02013         void)
02014 {
02015 
02016         int i, n;
02017         static struct Cif_unitdir *udp = (struct Cif_unitdir *) NULL;
02018         static struct Cif_urectbl *urp = (struct Cif_urectbl *) NULL;
02019 
02020         if (udp == (struct Cif_unitdir *) NULL) {
02021             if ((udp = (struct Cif_unitdir *) malloc (sizeof(struct Cif_unitdir))) ==
02022                 NULL) MEM_ERROR;
02023         }
02024         (void) memset ((char *)udp, '\0', sizeof(struct Cif_unitdir));
02025         udp->rectype = CIF_UNITDIR;
02026         udp->nsections = CIF_MAXRECORD;
02027         n = sizeof(struct Cif_urectbl) * CIF_MAXRECORD;
02028         if (urp == (struct Cif_urectbl *) NULL) {
02029             if ((urp = udp->ur = (struct Cif_urectbl *) malloc (n)) == NULL)
02030                 MEM_ERROR;
02031         }
02032         else {
02033             udp->ur = urp;
02034         }
02035         (void) memset ((char *)urp, '\0', n);
02036         for (i = 0; i < CIF_MAXRECORD; i++) {
02037                 if (unit_record[i])
02038                         urp[i].rectype = i;
02039         }
02040         addstruct (CIFGEN(udp));
02041 }
02042 
02043 /* --------------------------------------------------------------------------
02044  * merge_usages combines the use tables for usage records of the same id.
02045  * comp_use compares two use entries for sorted by qsort.
02046  * --------------------------------------------------------------------------
02047  */
02048 
02049 static int comp_use (
02050         struct Cif_use *u1,
02051         struct Cif_use *u2)
02052 {
02053         register int ret;
02054 
02055         if ((ret = ( u1->fid - u2->fid )) != 0)
02056                 return (ret);
02057         else if ((ret = ( u1->line - u2->line )) != 0)
02058                 return (ret);
02059         else
02060                 return ( u1->cpos - u2->cpos );
02061 }
02062 
02063 static int merge_usages (
02064         void)
02065 {
02066         int i, j, n;
02067         int numu;                                                       /* number of usage records */
02068         int nuses;                                                      /* number of uses */
02069         int si;                                                         /* usage array scanning index */
02070         int ti;                                                         /* usage array trailing index */
02071         struct Cif_usage **up;                  /* array of pointers to usage records */
02072         struct Cif_use *use;                            /* pointer to combined use array */
02073         struct Cif_use *use1, *use2;    /* pointers for moving use entries */
02074 
02075         struct Cif_generic *cifp1;              /* cif record pointer */
02076         struct Cif_urectbl *urp;
02077 
02078         /* Check if duplicate usage ids present */
02079 
02080         numu = patbl[CIF_USAGE].next;
02081         up = (struct Cif_usage **)patbl[CIF_USAGE].aptr;
02082 
02083         if (numu > global_nuses_allocated) {
02084             if (global_nuses == (int *) NULL)
02085                 global_nuses = (int *) malloc(numu * sizeof(int));
02086             else {
02087                 global_nuses = (int *) realloc(global_nuses,
02088                                                numu * sizeof(int));
02089             }
02090             global_nuses_allocated = numu;
02091         }
02092         memset((char *) global_nuses, '\0', numu * sizeof(int));
02093 
02094         for (si = 0; si < numu-1; si++) {
02095             if ( up[si]->symid == up[si+1]->symid) break;
02096             global_nuses[si] = 1;
02097         }
02098 
02099         if (si < numu - 1) {
02100 
02101                 /* Scan usages, merging records where ids are the same */
02102 
02103                 si = ti = 0;
02104                 while (si < numu) {
02105                         if (si == numu-1 ||
02106                             up[si]->symid != up[si+1]->symid ||
02107                             up[si]->nmembs !=  up[si+1]->nmembs) {
02108 
02109                             /* single usage for this id, copy it. */
02110                             global_nuses[ti] = 1;
02111                             *up[ti++] = *up[si++];
02112 
02113                         }
02114                         else {
02115                                 /* Multiple usages - find number, combine, and sort them */
02116                                 nuses = up[si]->nuses;;
02117                                 for (n = 1; si+n < numu && up[si+n]->symid == up[si]->symid; n++) {
02118 
02119                                     /*
02120                                      * number of parent symbold ids, eg a in a%b is different,
02121                                      * so this usage is not identical to the last
02122                                      */
02123 
02124                                     if (up[si]->nmembs !=  up[si+n]->nmembs)
02125                                         break;
02126 
02127                                     for (i = 0; i < (int) up[si]->nmembs; i++) {
02128                                         if (up[si]->membs[i] != up[si+n]->membs[i])
02129                                             break;
02130                                     }
02131 
02132                                     /*
02133                                      * If we didn't get to the end, a difference was found,
02134                                      * so this usage is not idenical to the last
02135                                      */
02136 
02137                                     if (i < (int) up[si]->nmembs)
02138                                         break;
02139 
02140                                     nuses += up[si+n]->nuses;
02141                                 }
02142 
02143                                 /* Combine all of the usages into one new record */
02144 
02145                                 if ((use = (struct Cif_use *) malloc (sizeof(struct Cif_use)*nuses))
02146                                          == NULL) MEM_ERROR;
02147 
02148                                 use1 = use;
02149                                 for (i = 0; i < n; i++) {
02150                                         use2 = up[si+i]->use;
02151                                         for (j = 0; j < (int) up[si+i]->nuses; j++)
02152                                                 (use1++)[0] = (use2++)[0];
02153                                 }
02154 
02155                                 /* Sort the usages on fid, line number and column position */
02156 
02157                                 (void) qsort ((char *)use,
02158                                               nuses, sizeof(struct Cif_use),
02159                                               (int(*)()) comp_use);
02160 
02161                                 /*
02162                                  * Put the new usage record back into the list;
02163                                  * note, ti must be <= si, so never overwrite anything
02164                                  * that we are about to read
02165                                  */
02166 
02167                                 up[ti]->nuses = nuses;
02168                                 up[ti]->symid = up[si]->symid;
02169                                 up[ti]->nmembs = up[si]->nmembs;
02170                                 up[ti]->membs = up[si]->membs;
02171                                 up[ti]->use = use;
02172 
02173                                 global_nuses[ti] = nuses;
02174 
02175                                 si += n;
02176                                 ti++;
02177                         }
02178                 }
02179                 patbl[CIF_USAGE].next = ti;
02180 
02181                 /* Update the unitdir record entry */
02182 
02183                 cifp1 = *(patbl[CIF_UNITDIR].aptr);
02184                 urp = CIFUDIR(cifp1)->ur;
02185                 urp[CIF_USAGE].nrecords = ti;
02186         }
02187 
02188         return (0);
02189 }
02190 
02191 /* --------------------------------------------------------------------------
02192  * write_header writes out the records that go at the head of the file.
02193  * --------------------------------------------------------------------------
02194  */
02195 
02196 /* --- output order of record types in output file trailer section --- */
02197 #define HRECORDS 15                             /* number of trailer record types */
02198 static const int horder[HRECORDS] = {
02199         CIF_CIFHDR,
02200         CIF_FILEDIR,
02201         CIF_SRCFILE,
02202         CIF_FILE,
02203         CIF_INCLUDE,
02204         CIF_SRC_POS,
02205         CIF_ORIG_CMD,
02206         CIF_EDOPTS,
02207         CIF_MACH_CHAR,
02208         CIF_MISC_OPTS,
02209         CIF_F90_MISC_OPTS,
02210         CIF_OPT_OPTS,
02211         CIF_F90_OPT_OPTS,
02212         CIF_C_OPTS,
02213         CIF_SUMMARY
02214 };
02215 
02216 static int write_header (
02217         void)
02218 {
02219 
02220         int i, j, rtype;
02221         long status;
02222         struct Cif_generic *sp;
02223 
02224         /* Sort the CIF_FILE records.  Write 'em out. */
02225 
02226         if (patbl[CIF_FILE].next > 1)
02227                 (void) qsort ((char *)patbl[CIF_FILE].aptr, patbl[CIF_FILE].next,
02228                         sizeof(struct Cif_generic *), qcompare[CIF_FILE]);
02229 
02230         sp = *(patbl[CIF_CIFHDR].aptr);
02231         CIFHDR(sp)->cont_id = 1;
02232         CIFHDR(sp)->srcfid = get_srcfid();  /* set the mapped srcfid */
02233 
02234         /*
02235          * We are writing a cifconv mode binary file, so set the bintype
02236          * to show that cifconv wrote this cif file
02237          */
02238 
02239         CIFHDR(sp)->bintype = CIF_FORM_CIFCONV;
02240 
02241         if (canpos == True)
02242                 CIFHDR(sp)->posinfo = 1;
02243         for (i = 0; i < HRECORDS; i++) {
02244                 rtype = horder[i];
02245                 if (rtype == CIF_FILEDIR && canpos == True) {
02246                         if ((fdirpos = Cif_Getpos (outfd)) < 0)
02247                                 OUT_ERROR ("positioning", outfd, fdirpos);
02248                 }
02249                 for (j = 0; j < patbl[rtype].next; j++) {
02250                         sp = (patbl[rtype].aptr)[j];
02251                         if ((status = Cif_Putrecord(outfd, sp)) < 0)
02252                                 OUT_ERROR ("writing", outfd, status);
02253                 }
02254         }
02255 
02256         return (0);
02257 
02258 }
02259 
02260 static int get_srcfid (
02261         void)
02262 {
02263         struct Cif_generic *sp, **spp;
02264         int rcnt, srcfid;
02265 
02266         srcfid = 0;
02267         spp = patbl[CIF_SRCFILE].aptr;
02268         for (rcnt = 0; rcnt < patbl[CIF_SRCFILE].next; rcnt++) {
02269                 sp = *spp++;
02270                 srcfid = CIFSRC(sp)->fid;
02271         }
02272         return(srcfid);
02273 }
02274 
02275 
02276 /* --------------------------------------------------------------------------
02277  * write_unit writes out all of the records for one unit from memory.
02278  * --------------------------------------------------------------------------
02279  */
02280 
02281 /* --- output order of record types in each unit of CIF --- */
02282 #define URECORDS 54                             /* number of unit record types */
02283 static const int uorder[URECORDS] = {
02284         CIF_UNIT,
02285         CIF_UNITDIR,
02286         CIF_ENTRY,
02287         CIF_COMBLK,
02288         CIF_OBJECT,
02289         CIF_CONST,
02290         CIF_NAMELIST,
02291         CIF_C_ENTRY,
02292         CIF_C_OBJECT,
02293         CIF_C_LINT_DIRECTIVE,
02294         CIF_C_MACRO_DEF,
02295         CIF_C_MACRO_UNDEF,
02296         CIF_C_MACRO_USAGE,
02297         CIF_C_ENTRY_END,
02298         CIF_C_TAG,
02299         CIF_C_CONST,
02300         CIF_LABEL,
02301         CIF_CALLSITE,
02302         CIF_USAGE,
02303         CIF_STMT_TYPE,
02304         CIF_LOOP,
02305         CIF_MESSAGE,
02306         CIF_ND_MSG,
02307         CIF_CDIR,
02308         CIF_CDIR_DOSHARED,
02309         CIF_GEOMETRY,
02310         CIF_CONTINUATION,
02311         CIF_TRANSFORM,
02312         CIF_F90_CALLSITE,
02313         CIF_F90_COMBLK,
02314         CIF_F90_CONST,
02315         CIF_F90_ENTRY,
02316         CIF_F90_LOOP,
02317         CIF_F90_DERIVED_TYPE,
02318         CIF_F90_LABEL,
02319         CIF_F90_NAMELIST,
02320         CIF_F90_OBJECT,
02321         CIF_F90_BEGIN_SCOPE,
02322         CIF_F90_END_SCOPE,
02323         CIF_F90_SCOPE_INFO,
02324         CIF_F90_USE_MODULE,
02325         CIF_F90_RENAME,
02326         CIF_F90_INT_BLOCK,
02327         CIF_F90_VECTORIZATION,
02328         CIF_CC_TYPE,
02329         CIF_CC_ENTRY,
02330         CIF_CC_OBJ,
02331         CIF_CC_SUBTYPE,
02332         CIF_CC_ENUM,
02333         CIF_CC_EXPR,
02334         CIF_BE_NODE,
02335         CIF_BE_FID,
02336         CIF_C_MESSAGE,
02337         CIF_ENDUNIT
02338 };
02339 
02340 static int write_unit (
02341         int fd,                                                         /* cif output file descriptor */
02342         enum Boolean markpos,                   /* set if positioning should be done */
02343         enum Boolean merge_use)                 /* set if usage records should be merged */
02344 {
02345 
02346         int i, j, rtype;
02347         long status, savepos;
02348         char *name;
02349         struct Cif_generic *sp;
02350         struct Cif_urectbl *urp;
02351         struct Cif_unittbl *utp;
02352         int numu;                                                       /* number of usage records */
02353         struct Cif_usage **up;                  /* array of pointers to usage records */
02354         int si;                                 /* usage array scanning index */
02355         struct Cif_generic **spp;       
02356 
02357         /* Get the file position of the unit and save in the file directory */
02358 
02359         if (markpos) {
02360                 name = CIFUNIT(*patbl[CIF_UNIT].aptr)->name;
02361                 utp = CIFFDIR(*patbl[CIF_FILEDIR].aptr)->ut;
02362                 i = CIFFDIR(*patbl[CIF_FILEDIR].aptr)->nunits;
02363                 for (j = 0; j < i; j++)
02364                         if (strcmp(name,utp[j].name) == 0 &&
02365                             utp[j].unitpos == 0) break;
02366 
02367                 if ((status = utp[j].unitpos = Cif_Getpos(fd)) < 0)
02368                         OUT_ERROR ("positioning", fd, status);
02369         }
02370 
02371         /* Sort the unit records.  Merge usage records as needed. */
02372 
02373         for (rtype = 0; rtype < CIF_MAXRECORD; rtype++) {
02374                 if (unit_record[rtype] && patbl[rtype].next > 1 &&
02375                                  qcompare[rtype] != 0)
02376                         (void) qsort ((char *)patbl[rtype].aptr, patbl[rtype].next,
02377                                 sizeof(struct Cif_generic *), qcompare[rtype]);
02378         }
02379 
02380         /* Reset the cif_stmt_type records; ie the rectype back
02381          * to CIF_STMT_TYPE
02382          */
02383 
02384         if (lang == CIF_LG_C || lang == CIF_LG_CC) {
02385                 spp = patbl[CIF_STMT_TYPE].aptr;
02386                 for (i = 0; i < patbl[CIF_STMT_TYPE].next; i++) {
02387                         CIFSTMT(*spp++)->rectype = CIF_STMT_TYPE;
02388                 }
02389         }
02390 
02391         /* Merge the usages records on symbol ids */
02392 
02393         if (merge_use)
02394             (void) merge_usages();
02395 
02396 /* merge_usages always returns 0
02397                 if ((i = merge_usages ()) < 0) return (i);
02398 */
02399 
02400         /* Write the records out in order as specified by the uorder table.  Get
02401          * the file position at the start of new record type and stick it in the
02402          * unit directory.  After the end_unit record, save the file postion,
02403          * rewrite the unit directory and restore the file position.
02404          */
02405 
02406         sp = *(patbl[CIF_UNITDIR].aptr);
02407         urp = CIFUDIR(sp)->ur;
02408         for (i = 0; i < URECORDS; i++) {
02409                 rtype = uorder[i];
02410                 if (patbl[rtype].next > 0) {
02411                         if (markpos) {
02412                                 if ((status = Cif_Getpos (fd)) < 0)
02413                                         OUT_ERROR ("positioning", fd, status);
02414                         }
02415                         else
02416                                 status = 0;
02417                         urp[rtype].recpos = status;
02418                         for (j = 0; j < patbl[rtype].next; j++) {
02419                                 if ((status = Cif_Putrecord (fd, (patbl[rtype].aptr)[j])) < 0)
02420                                         OUT_ERROR ("writing", fd, status);
02421                             }
02422                 }
02423         }
02424 
02425         /* Free up space allocated for merged usages */
02426 
02427         if (merge_use &&
02428             global_nuses != (int *) NULL) {
02429             numu = patbl[CIF_USAGE].next;
02430             up = (struct Cif_usage **)patbl[CIF_USAGE].aptr;
02431             for (si = 0; si < numu; si++) {
02432                 if (global_nuses[si] > 1)
02433                     free((char *) up[si]->use);
02434             }
02435         }
02436 
02437         if (markpos) {
02438                 if ((savepos = Cif_Getpos (fd)) < 0)
02439                         OUT_ERROR ("positioning", fd, status);
02440                 if ((status = Cif_Setpos (fd, urp[CIF_UNITDIR].recpos)) < 0)
02441                         OUT_ERROR ("positioning", fd, status);
02442                 if ((status = Cif_Putrecord (fd, *(patbl[CIF_UNITDIR].aptr))) < 0)
02443                         OUT_ERROR ("writing", fd, status);
02444                 if ((status = Cif_Setpos (fd, savepos)) < 0)
02445                         OUT_ERROR ("positioning", fd, status);
02446         }
02447 
02448         return (0);
02449 }
02450 
02451 #ifdef DEBUG
02452 /* --------------------------------------------------------------------------
02453  * dump_patbl displays the contents of patbl for debugging purposes.
02454  * --------------------------------------------------------------------------
02455  */
02456 void dump_patbl (
02457         FILE *fd)
02458 {
02459         int i, j;
02460         struct Cif_generic **rptr;
02461 
02462         for (i = 0; i < CIF_MAXRECORD; i++) {
02463                 if (patbl[i].psize != 0) {
02464                         (void) fprintf (fd, "\npatbl[%d] aptr= %d  psize= %d  next= %d\n",
02465                                                 i, patbl[i].aptr, patbl[i].psize, patbl[i].next);
02466                         rptr = patbl[i].aptr;
02467                         for (j = 0; j < patbl[i].next; j++) {
02468                                 (void) fprintf (fd, "    item %4d  *aptr= %d  rtype= %d\n",
02469                                          j, rptr, (*rptr)->rectype);
02470                                 rptr++;
02471                         }
02472                 }
02473         }
02474         
02475 }
02476 
02477 /* --------------------------------------------------------------------------
02478  * valid_patbl checks the validity of the patbl and offers a convenient
02479  * place for the debugger to set a breakpoint.
02480  * --------------------------------------------------------------------------
02481  */
02482 static int valid_patbl (
02483         void)
02484 {
02485         int i, j;
02486         struct Cif_generic **rptr;
02487 
02488         for (i = 0; i < CIF_MAXRECORD; i++) {
02489                 if (patbl[i].psize != 0) {
02490                         rptr = patbl[i].aptr;
02491                         for (j = 0; j < patbl[i].next; j++) {
02492                                 if ((*rptr)->rectype != i)
02493                                         return (0);
02494                                 rptr++;
02495                         }
02496                 }
02497         }
02498         return (1);
02499 }
02500 #endif
02501 
02502 /* --------------------------------------------------------------------------
02503  * init_id initializes an Id_tbl so it can start receiving ids via add_id.
02504  * --------------------------------------------------------------------------
02505  */
02506 static void init_id (
02507         struct Id_tbl *idtp)
02508 {
02509     idtp->cur = 1;
02510     (idtp->tbl)[0] = 0;
02511 }
02512 
02513 /* --------------------------------------------------------------------------
02514  * add_id adds a new id value to an Id_tbl tbl.  The table is expanded if
02515  * neccessary.
02516  * --------------------------------------------------------------------------
02517  */
02518 static void add_id (
02519         struct Id_tbl *idtp,            /* ptr to Id_tbl structure that will receive id */
02520         long id)                                                /* value of id to add */
02521 {
02522 
02523         if (idtp->cur >= idtp->max) {
02524                 idtp->max += ID_BUMP;
02525                 if ((idtp->tbl = (long *) realloc ((char *)idtp->tbl,
02526                                 sizeof(long)*idtp->max)) == NULL)
02527                         MEM_ERROR;
02528         }
02529         idtp->tbl[idtp->cur++] = id;
02530 }
02531 
02532 /* --------------------------------------------------------------------------
02533  * comp_ids compares two symbol ids (longs) for use by qsort.
02534  * --------------------------------------------------------------------------
02535  */
02536 static int comp_ids (
02537         long *id1, 
02538         long *id2)
02539 {
02540         return (*id1 - *id2);
02541 }
02542 
02543 /* --------------------------------------------------------------------------
02544  * get_id retrieves the new value for a remapped id given the original value.
02545  * The tbl array will contain all original ids in ascending order.  get_id
02546  * performs a binary search of the array and returns the array index of the
02547  * original value.
02548  * --------------------------------------------------------------------------
02549  */
02550 static long get_id (
02551         struct Id_tbl *idtp,                    /* ptr to Id_tbl to scan for id value */
02552         long id)                                                        /* original id value */
02553 {
02554 
02555         int lower = 1;                          /* tbl search boundaries */
02556         int upper = idtp->cur-1;
02557         int mid;
02558 
02559         if (id == 0)
02560                 return (0);
02561 
02562 
02563         mid = (upper + lower) / 2;
02564 
02565         while (lower < upper) {
02566 
02567                 if (id < (idtp->tbl)[mid])
02568                         upper = mid - 1;
02569                 else if (id > (idtp->tbl)[mid])
02570                         lower = mid + 1;
02571                 else
02572                         break;
02573 
02574                 mid = (upper + lower) / 2;
02575         }
02576 
02577         /*
02578          * Now check to see if the lookup was successful; the only way that this
02579          * would not be the case, would be if the compiler has generated invalid
02580          * object id's; not alot we can do about them, but report the error.
02581          */
02582 
02583         if ((idtp->tbl)[mid] != id) {
02584 
02585             if (global_error_report == True) {
02586                 (void) fprintf(stderr,
02587                                "libcif : Invalid id in cif %s.\nClosest match to %d is %d, so using 0 in output record.\n",
02588                                global_outfile, id, (idtp->tbl)[mid]);
02589             }
02590             mid = 0;
02591         }
02592 
02593         return (mid);
02594 
02595 }
02596 
02597 /* --------------------------------------------------------------------------
02598  * remap_symbols scans the patbl contents for the current unit and remaps the
02599  * symbol and file id values.  It is assumed that the file ids have already
02600  * been accumulated and sorted.  remap_symbols collects all the symbol ids,
02601  * sorts 'em, and then changes all ids (both file and symbol) to the new values.
02602  * --------------------------------------------------------------------------
02603  */
02604 static void remap_symbols (
02605         void)
02606 {
02607 
02608         struct Cif_generic *sp, **spp;  
02609         int rcnt, i, j;
02610 
02611         init_id (&sid);
02612 
02613         /* Scan patbl for those structure that define symbol ids and add them
02614          * to the symbol table list.
02615          */
02616 
02617         spp = patbl[CIF_COMBLK].aptr;
02618         for (rcnt = 0; rcnt < patbl[CIF_COMBLK].next; rcnt++)
02619                 add_id (&sid, CIFCB(*spp++)->symid);
02620 
02621         spp = patbl[CIF_CONST].aptr;
02622         for (rcnt = 0; rcnt < patbl[CIF_CONST].next; rcnt++)
02623                 add_id (&sid, CIFCON(*spp++)->symid);
02624 
02625         spp = patbl[CIF_ENTRY].aptr;
02626         for (rcnt = 0; rcnt < patbl[CIF_ENTRY].next; rcnt++)
02627                 add_id (&sid, CIFENTRY(*spp++)->symid);
02628 
02629         spp = patbl[CIF_LABEL].aptr;
02630         for (rcnt = 0; rcnt < patbl[CIF_LABEL].next; rcnt++)
02631                 add_id (&sid, CIFLABEL(*spp++)->symid);
02632 
02633         spp = patbl[CIF_NAMELIST].aptr;
02634         for (rcnt = 0; rcnt < patbl[CIF_NAMELIST].next; rcnt++)
02635                 add_id (&sid, CIFNL(*spp++)->symid);
02636 
02637         spp = patbl[CIF_OBJECT].aptr;
02638         for (rcnt = 0; rcnt < patbl[CIF_OBJECT].next; rcnt++)
02639                 add_id (&sid, CIFOBJ(*spp++)->symid);
02640 
02641         spp = patbl[CIF_C_CONST].aptr;
02642         for (rcnt = 0; rcnt < patbl[CIF_C_CONST].next; rcnt++)
02643                 add_id (&sid, CIFCCON(*spp++)->symid);
02644 
02645         spp = patbl[CIF_C_ENTRY].aptr;
02646         for (rcnt = 0; rcnt < patbl[CIF_C_ENTRY].next; rcnt++)
02647                 add_id (&sid, CIFCENTRY(*spp++)->symid);
02648 
02649         spp = patbl[CIF_C_OBJECT].aptr;
02650         for (rcnt = 0; rcnt < patbl[CIF_C_OBJECT].next; rcnt++)
02651                 add_id (&sid, CIFCOBJ(*spp++)->symid);
02652 
02653         spp = patbl[CIF_C_LINT_DIRECTIVE].aptr;
02654         for (rcnt = 0; rcnt < patbl[CIF_C_LINT_DIRECTIVE].next; rcnt++)
02655                 add_id (&sid, CIFCLDIR(*spp++)->objid);
02656 
02657         spp = patbl[CIF_C_MACRO_DEF].aptr;
02658         for (rcnt = 0; rcnt < patbl[CIF_C_MACRO_DEF].next; rcnt++)
02659                 add_id (&sid, CIFCMDEF(*spp++)->symid);
02660 
02661         spp = patbl[CIF_C_TAG].aptr;
02662         for (rcnt = 0; rcnt < patbl[CIF_C_TAG].next; rcnt++)
02663                 add_id (&sid, CIFCTAG(*spp++)->tagid);
02664 
02665 
02666 
02667         spp = patbl[CIF_CC_TYPE].aptr;
02668         for (rcnt = 0; rcnt < patbl[CIF_CC_TYPE].next; rcnt++) {
02669                 sp = *spp++;
02670                 add_id (&sid, CIFCCTYPE(sp)->symid);
02671                 j = CIFCCTYPE(sp)->nmem;
02672                 for (i = 0; i < j; i++ ) {
02673                     add_id (&sid, CIFCCTYPE(sp)->mem[i]);
02674                 }
02675         }
02676 
02677         spp = patbl[CIF_CC_ENTRY].aptr;
02678         for (rcnt = 0; rcnt < patbl[CIF_CC_ENTRY].next; rcnt++) {
02679                 sp = *spp++;
02680                 add_id (&sid, CIFCCENT(sp)->symid);
02681                 add_id (&sid, CIFCCENT(sp)->fsymid);
02682                 j = CIFCCENT(sp)->nparam;
02683                 for (i = 0; i < j; i++ ) {
02684                     add_id (&sid, CIFCCENT(sp)->param[i]);
02685                 }
02686         }
02687 
02688         spp = patbl[CIF_CC_OBJ].aptr;
02689         for (rcnt = 0; rcnt < patbl[CIF_CC_OBJ].next; rcnt++)
02690                 add_id (&sid, CIFCCOBJ(*spp++)->symid);
02691 
02692         spp = patbl[CIF_CC_SUBTYPE].aptr;
02693         for (rcnt = 0; rcnt < patbl[CIF_CC_SUBTYPE].next; rcnt++)
02694                 add_id (&sid, CIFCCSUB(*spp++)->symid);
02695 
02696         spp = patbl[CIF_CC_ENUM].aptr;
02697         for (rcnt = 0; rcnt < patbl[CIF_CC_ENUM].next; rcnt++)
02698                 add_id (&sid, CIFCCENUM(*spp++)->symid);
02699 
02700 
02701 
02702         spp = patbl[CIF_F90_COMBLK].aptr;
02703         for (rcnt = 0; rcnt < patbl[CIF_F90_COMBLK].next; rcnt++)
02704                 add_id (&sid, CIFF90CB(*spp++)->symid);
02705 
02706         spp = patbl[CIF_F90_CONST].aptr;
02707         for (rcnt = 0; rcnt < patbl[CIF_F90_CONST].next; rcnt++)
02708                 add_id (&sid, CIFF90CON(*spp++)->symid);
02709 
02710         spp = patbl[CIF_F90_ENTRY].aptr;
02711         for (rcnt = 0; rcnt < patbl[CIF_F90_ENTRY].next; rcnt++) {
02712                 add_id (&sid, CIFF90ENTRY(*spp++)->symid);
02713             }
02714 
02715         spp = patbl[CIF_F90_LABEL].aptr;
02716         for (rcnt = 0; rcnt < patbl[CIF_F90_LABEL].next; rcnt++)
02717                 add_id (&sid, CIFF90LABEL(*spp++)->symid);
02718 
02719         spp = patbl[CIF_F90_NAMELIST].aptr;
02720         for (rcnt = 0; rcnt < patbl[CIF_F90_NAMELIST].next; rcnt++)
02721                 add_id (&sid, CIFF90NL(*spp++)->symid);
02722 
02723         spp = patbl[CIF_F90_OBJECT].aptr;
02724         for (rcnt = 0; rcnt < patbl[CIF_F90_OBJECT].next; rcnt++) {
02725 /*
02726                 add_id (&sid, CIFF90OBJ(*spp)->storageid);
02727 */
02728                 add_id (&sid, CIFF90OBJ(*spp++)->symid);
02729             }
02730 
02731         spp = patbl[CIF_F90_BEGIN_SCOPE].aptr;
02732         for (rcnt = 0; rcnt < patbl[CIF_F90_BEGIN_SCOPE].next; rcnt++) {
02733                 add_id (&sid, CIFF90BS(*spp++)->scopeid);
02734                 /* add_id (&sid, CIFF90BS(*spp++)->symid); */
02735             }
02736 
02737         spp = patbl[CIF_F90_INT_BLOCK].aptr;
02738         for (rcnt = 0; rcnt < patbl[CIF_F90_INT_BLOCK].next; rcnt++) {
02739                 add_id (&sid, CIFF90IB(*spp)->intid);
02740                 for (i = 0; i < (int) CIFF90IB(*spp)->numints; i++)
02741                         add_id (&sid, CIFF90IB(*spp)->procids[i]);
02742                 spp++;
02743         }
02744 
02745         spp = patbl[CIF_F90_RENAME].aptr;
02746         for (rcnt = 0; rcnt < patbl[CIF_F90_RENAME].next; rcnt++) {
02747                 add_id (&sid, CIFF90RN(*spp)->nameid);
02748                 spp++;
02749         }
02750 
02751         spp = patbl[CIF_GEOMETRY].aptr;
02752         for (rcnt = 0; rcnt < patbl[CIF_GEOMETRY].next; rcnt++)
02753                 add_id (&sid, CIFGEOM(*spp++)->geomid);
02754 
02755         spp = patbl[CIF_F90_DERIVED_TYPE].aptr;
02756         for (rcnt = 0; rcnt < patbl[CIF_F90_DERIVED_TYPE].next; rcnt++) {
02757             add_id (&sid, CIFF90DTYPE(*spp++)->symid);
02758         }
02759 
02760 
02761         /* Sort the accumulated ids, then go thru and replace all the ids. */
02762 
02763         (void) qsort ((char *)sid.tbl, sid.cur, sizeof(long), (int(*)()) comp_ids);
02764 
02765         spp = patbl[CIF_CALLSITE].aptr;
02766         for (rcnt = 0; rcnt < patbl[CIF_CALLSITE].next; rcnt++) {
02767                 sp = *spp++;
02768                 CIFCS(sp)->entryid = get_id (&sid, CIFCS(sp)->entryid);
02769 #ifdef REMAP_FID
02770                 CIFCS(sp)->fid = get_id (&fid, CIFCS(sp)->fid);
02771 #endif
02772                 for (i = 0; i < (int) CIFCS(sp)->nargs; i++)
02773                         CIFCS(sp)->argids[i] = get_id (&sid, CIFCS(sp)->argids[i]);
02774         }
02775 
02776         spp = patbl[CIF_COMBLK].aptr;
02777         for (rcnt = 0; rcnt < patbl[CIF_COMBLK].next; rcnt++) {
02778                 sp = *spp++;
02779                 CIFCB(sp)->symid = get_id (&sid, CIFCB(sp)->symid);
02780         }
02781 
02782         spp = patbl[CIF_CONST].aptr;
02783         for (rcnt = 0; rcnt < patbl[CIF_CONST].next; rcnt++) {
02784                 sp = *spp++;
02785                 CIFCON(sp)->symid = get_id (&sid, CIFCON(sp)->symid);
02786         }
02787 
02788         spp = patbl[CIF_ENTRY].aptr;
02789         for (rcnt = 0; rcnt < patbl[CIF_ENTRY].next; rcnt++) {
02790                 sp = *spp++;
02791                 CIFENTRY(sp)->symid = get_id (&sid, CIFENTRY(sp)->symid);
02792                 for (i = 0; i < (int) CIFENTRY(sp)->nargs; i++)
02793                         CIFENTRY(sp)->argids[i] = get_id (&sid, CIFENTRY(sp)->argids[i]);
02794         }
02795 
02796         spp = patbl[CIF_LABEL].aptr;
02797         for (rcnt = 0; rcnt < patbl[CIF_LABEL].next; rcnt++) {
02798                 sp = *spp++;
02799                 CIFLABEL(sp)->symid = get_id (&sid, CIFLABEL(sp)->symid);
02800         }
02801 
02802         spp = patbl[CIF_LOOP].aptr;
02803         for (rcnt = 0; rcnt < patbl[CIF_LOOP].next; rcnt++) {
02804                 sp = *spp++;
02805 #ifdef REMAP_FID
02806                 CIFLOOP(sp)->sfid = get_id (&fid, CIFLOOP(sp)->sfid);
02807                 CIFLOOP(sp)->efid = get_id (&fid, CIFLOOP(sp)->efid);
02808 #endif
02809                 CIFLOOP(sp)->labelid = get_id (&sid, CIFLOOP(sp)->labelid);
02810                 CIFLOOP(sp)->symid = get_id (&sid, CIFLOOP(sp)->symid);
02811         }
02812 
02813 #ifdef REMAP_FID
02814         spp = patbl[CIF_MESSAGE].aptr;
02815         for (rcnt = 0; rcnt < patbl[CIF_MESSAGE].next; rcnt++) {
02816                 sp = *spp++;
02817                 CIFMSG(sp)->fid = get_id (&fid, CIFMSG(sp)->fid);
02818                 CIFMSG(sp)->pfid = get_id (&fid, CIFMSG(sp)->pfid);
02819         }
02820 #endif
02821 
02822         spp = patbl[CIF_NAMELIST].aptr;
02823         for (rcnt = 0; rcnt < patbl[CIF_NAMELIST].next; rcnt++) {
02824                 sp = *spp++;
02825                 CIFNL(sp)->symid = get_id (&sid, CIFNL(sp)->symid);
02826                 for (i = 0; i < (int) CIFNL(sp)->nids; i++)
02827                         CIFNL(sp)->ids[i] = get_id (&sid, CIFNL(sp)->ids[i]);
02828         }
02829 
02830         spp = patbl[CIF_OBJECT].aptr;
02831         for (rcnt = 0; rcnt < patbl[CIF_OBJECT].next; rcnt++) {
02832                 sp = *spp++;
02833                 CIFOBJ(sp)->symid = get_id (&sid, CIFOBJ(sp)->symid);
02834                 CIFOBJ(sp)->geomid = get_id (&sid, CIFOBJ(sp)->geomid);
02835                 CIFOBJ(sp)->pointer = get_id (&sid, CIFOBJ(sp)->pointer);
02836                 if (CIFOBJ(sp)->symclass == CIF_SC_COMMON || CIFOBJ(sp)->symclass ==
02837                     CIF_SC_EQUIV)
02838                 {
02839                         CIFOBJ(sp)->storage = get_id (&sid, CIFOBJ(sp)->storage);
02840                 }
02841         }
02842 
02843 #ifdef REMAP_FID
02844         spp = patbl[CIF_STMT_TYPE].aptr;
02845         for (rcnt = 0; rcnt < patbl[CIF_STMT_TYPE].next; rcnt++) {
02846                 sp = *spp++;
02847                 CIFSTMT(sp)->fid = get_id (&fid, CIFSTMT(sp)->fid);
02848                 if (CIFSTMT(sp)->efid > 0) {
02849                   CIFSTMT(sp)->efid = get_id (&fid, CIFSTMT(sp)->efid);
02850                 }
02851         }
02852 
02853         spp = patbl[CIF_UNIT].aptr;
02854         for (rcnt = 0; rcnt < patbl[CIF_UNIT].next; rcnt++) {
02855                 sp = *spp++;
02856                 CIFUNIT(sp)->fid = get_id (&fid, CIFUNIT(sp)->fid);
02857         }
02858 
02859         spp = patbl[CIF_ENDUNIT].aptr;
02860         for (rcnt = 0; rcnt < patbl[CIF_ENDUNIT].next; rcnt++) {
02861                 sp = *spp++;
02862                 CIFENDU(sp)->fid = get_id (&fid, CIFENDU(sp)->fid);
02863         }
02864 #endif
02865 
02866         spp = patbl[CIF_USAGE].aptr;
02867         for (rcnt = 0; rcnt < patbl[CIF_USAGE].next; rcnt++) {
02868                 struct Cif_use *use;
02869                 sp = *spp++;
02870                 CIFUSAGE(sp)->symid = get_id (&sid, CIFUSAGE(sp)->symid);
02871                 for (i = 0; i < (int) CIFUSAGE(sp)->nmembs; i++) {
02872                   CIFUSAGE(sp)->membs[i] = get_id (&sid, CIFUSAGE(sp)->membs[i]);
02873                 }
02874 #ifdef REMAP_FID
02875                 use = CIFUSAGE(sp)->use;
02876                 for (i = 0; i < (int) CIFUSAGE(sp)->nuses; i++) {
02877                         use->fid = get_id (&fid, use->fid);
02878                         use++;
02879                 }
02880 #endif
02881         }
02882 
02883 
02884 
02885 
02886         spp = patbl[CIF_CDIR].aptr;
02887         for (rcnt = 0; rcnt < patbl[CIF_CDIR].next; rcnt++) {
02888                 sp = *spp++;
02889 #ifdef REMAP_FID
02890                 CIFCDIR(sp)->fid = get_id (&fid, CIFCDIR(sp)->fid);
02891 #endif
02892                 for (i = 0; i < (int) CIFCDIR(sp)->nids; i++) {
02893                   CIFCDIR(sp)->ids[i] = get_id (&sid, CIFCDIR(sp)->ids[i]);
02894                 }
02895         }
02896 
02897         spp = patbl[CIF_CDIR_DOSHARED].aptr;
02898         for (rcnt = 0; rcnt < patbl[CIF_CDIR_DOSHARED].next; rcnt++) {
02899                 sp = *spp++;
02900 #ifdef REMAP_FID
02901                 CIFCDIRDO(sp)->fid = get_id (&fid, CIFCDIRDO(sp)->fid);
02902                 CIFCDIRDO(sp)->mfid = get_id (&fid, CIFCDIRDO(sp)->mfid);
02903 #endif
02904                 for (i = 0; i < (int) CIFCDIRDO(sp)->nids; i++) {
02905                   CIFCDIRDO(sp)->ids[i] = get_id (&sid, CIFCDIRDO(sp)->ids[i]);
02906                 }
02907         }
02908 
02909 
02910         spp = patbl[CIF_GEOMETRY].aptr;
02911         for (rcnt = 0; rcnt < patbl[CIF_GEOMETRY].next; rcnt++) {
02912                 struct Cif_geometry_dim *dim;
02913                 sp = *spp++;
02914                 CIFGEOM(sp)->geomid = get_id (&sid, CIFGEOM(sp)->geomid);
02915 #ifdef REMAP_FID
02916                 dim = CIFGEOM(sp)->dim;
02917                 for (i = 0; i < (int) CIFGEOM(sp)->ndims; i++) {
02918                         dim->wfid = get_id (&fid, dim->wfid);
02919                         dim->bfid = get_id (&fid, dim->bfid);
02920                         dim++;
02921                 }
02922 #endif
02923         }
02924 
02925 #ifdef REMAP_FID
02926         spp = patbl[CIF_CONTINUATION].aptr;
02927         for (rcnt = 0; rcnt < patbl[CIF_CONTINUATION].next; rcnt++) {
02928                 sp = *spp++;
02929                 CIFCONT(sp)->fid = get_id (&fid, CIFCONT(sp)->fid);
02930         }
02931 
02932         spp = patbl[CIF_TRANSFORM].aptr;
02933         for (rcnt = 0; rcnt < patbl[CIF_TRANSFORM].next; rcnt++) {
02934                 sp = *spp++;
02935                 CIFTRAN(sp)->fid = get_id (&fid, CIFTRAN(sp)->fid);
02936         }
02937 #endif
02938 
02939 
02940         spp = patbl[CIF_F90_CALLSITE].aptr;
02941         for (rcnt = 0; rcnt < patbl[CIF_F90_CALLSITE].next; rcnt++) {
02942                 sp = *spp++;
02943                 CIFF90CS(sp)->entryid = get_id (&sid, CIFF90CS(sp)->entryid);
02944 #ifdef REMAP_FID
02945                 CIFF90CS(sp)->fid = get_id (&fid, CIFF90CS(sp)->fid);
02946 #endif
02947                 CIFF90CS(sp)->procid = get_id(&sid, CIFF90CS(sp)->procid);
02948                 CIFF90CS(sp)->scopeid = get_id(&sid, CIFF90CS(sp)->scopeid);
02949                 for (i = 0; i < (int) CIFF90CS(sp)->nargs; i++) {
02950                         CIFF90CS(sp)->argids[i] = get_id (&sid, CIFF90CS(sp)->argids[i]);
02951 
02952                         for (j = 0; j < CIFF90CS(sp)->nmembs[i]; j++) {
02953 
02954                             CIFF90CS(sp)->membs[i][j] =
02955                                 get_id (&sid, CIFF90CS(sp)->membs[i][j]);
02956                         }
02957                 }
02958         }
02959 
02960         spp = patbl[CIF_F90_COMBLK].aptr;
02961         for (rcnt = 0; rcnt < patbl[CIF_F90_COMBLK].next; rcnt++) {
02962                 sp = *spp++;
02963                 CIFF90CB(sp)->symid = get_id (&sid, CIFF90CB(sp)->symid);
02964                 CIFF90CB(sp)->moduleid = get_id (&sid, CIFF90CB(sp)->moduleid);
02965                 CIFF90CB(sp)->scopeid = get_id (&sid, CIFF90CB(sp)->scopeid);
02966         }
02967 
02968         spp = patbl[CIF_F90_CONST].aptr;
02969         for (rcnt = 0; rcnt < patbl[CIF_F90_CONST].next; rcnt++) {
02970                 sp = *spp++;
02971                 CIFF90CON(sp)->symid = get_id (&sid, CIFF90CON(sp)->symid);
02972 #ifdef REMAP_FID
02973                 CIFF90CON(sp)->fid = get_id (&fid, CIFF90CON(sp)->fid);
02974 #endif
02975                 CIFF90CON(sp)->scopeid = get_id (&sid, CIFF90CON(sp)->scopeid);
02976         }
02977 
02978         spp = patbl[CIF_F90_ENTRY].aptr;
02979         for (rcnt = 0; rcnt < patbl[CIF_F90_ENTRY].next; rcnt++) {
02980                 sp = *spp++;
02981 
02982                 CIFF90ENTRY(sp)->symid = get_id (&sid, CIFF90ENTRY(sp)->symid);
02983                 CIFF90ENTRY(sp)->scopeid = get_id (&sid, CIFF90ENTRY(sp)->scopeid);
02984                 CIFF90ENTRY(sp)->moduleid = get_id (&sid, CIFF90ENTRY(sp)->moduleid);
02985                 CIFF90ENTRY(sp)->resultid = get_id (&sid, CIFF90ENTRY(sp)->resultid);
02986                 for (i = 0; i < (int) CIFF90ENTRY(sp)->nargs; i++)
02987                         CIFF90ENTRY(sp)->argids[i] = get_id (&sid, CIFF90ENTRY(sp)->argids[i]);
02988         }
02989 
02990         spp = patbl[CIF_F90_LABEL].aptr;
02991         for (rcnt = 0; rcnt < patbl[CIF_F90_LABEL].next; rcnt++) {
02992                 sp = *spp++;
02993                 CIFF90LABEL(sp)->symid = get_id (&sid, CIFF90LABEL(sp)->symid);
02994                 CIFF90LABEL(sp)->scopeid = get_id (&sid, CIFF90LABEL(sp)->scopeid);
02995         }
02996 
02997         spp = patbl[CIF_F90_LOOP].aptr;
02998         for (rcnt = 0; rcnt < patbl[CIF_F90_LOOP].next; rcnt++) {
02999                 sp = *spp++;
03000 #ifdef REMAP_FID
03001                 CIFF90LOOP(sp)->sfid = get_id (&fid, CIFF90LOOP(sp)->sfid);
03002                 CIFF90LOOP(sp)->efid = get_id (&fid, CIFF90LOOP(sp)->efid);
03003 #endif
03004                 CIFF90LOOP(sp)->labelid = get_id (&sid, CIFF90LOOP(sp)->labelid);
03005                 CIFF90LOOP(sp)->symid = get_id (&sid, CIFF90LOOP(sp)->symid);
03006                 CIFF90LOOP(sp)->scopeid = get_id (&sid, CIFF90LOOP(sp)->scopeid);
03007                 CIFF90LOOP(sp)->nameid = get_id (&sid, CIFF90LOOP(sp)->nameid);
03008         }
03009 
03010         spp = patbl[CIF_F90_NAMELIST].aptr;
03011         for (rcnt = 0; rcnt < patbl[CIF_F90_NAMELIST].next; rcnt++) {
03012                 sp = *spp++;
03013                 CIFF90NL(sp)->symid = get_id (&sid, CIFF90NL(sp)->symid);
03014                 CIFF90NL(sp)->scopeid = get_id (&sid, CIFF90NL(sp)->scopeid);
03015                 CIFF90NL(sp)->moduleid = get_id (&sid, CIFF90NL(sp)->moduleid);
03016                 for (i = 0; i < (int) CIFF90NL(sp)->nids; i++)
03017                         CIFF90NL(sp)->ids[i] = get_id (&sid, CIFF90NL(sp)->ids[i]);
03018         }
03019 
03020         spp = patbl[CIF_F90_OBJECT].aptr;
03021         for (rcnt = 0; rcnt < patbl[CIF_F90_OBJECT].next; rcnt++) {
03022                 sp = *spp++;
03023 
03024                 CIFF90OBJ(sp)->symid = get_id (&sid, CIFF90OBJ(sp)->symid);
03025                 CIFF90OBJ(sp)->scopeid = get_id (&sid, CIFF90OBJ(sp)->scopeid);
03026 
03027                 if (CIFF90OBJ(sp)->symclass == CIF_F90_SC_COMMON ||
03028                     CIFF90OBJ(sp)->symclass == CIF_F90_SC_MODULE ||
03029                     CIFF90OBJ(sp)->symclass == CIF_F90_SC_EQUIV ||
03030                     CIFF90OBJ(sp)->symclass == CIF_F90_SC_NAMED_CONST)
03031 
03032                     CIFF90OBJ(sp)->storageid =
03033                         get_id (&sid, CIFF90OBJ(sp)->storageid);
03034 
03035                 CIFF90OBJ(sp)->geomid =
03036                     get_id (&sid, CIFF90OBJ(sp)->geomid);
03037                 CIFF90OBJ(sp)->pointerid =
03038                     get_id (&sid, CIFF90OBJ(sp)->pointerid);
03039             }
03040 
03041         spp = patbl[CIF_F90_DERIVED_TYPE].aptr;
03042         for (rcnt = 0; rcnt < patbl[CIF_F90_DERIVED_TYPE].next; rcnt++) {
03043                 sp = *spp++;
03044                 CIFF90DTYPE(sp)->symid = get_id (&sid, CIFF90DTYPE(sp)->symid);
03045                 CIFF90DTYPE(sp)->scopeid = get_id (&sid, CIFF90DTYPE(sp)->scopeid);
03046                 CIFF90DTYPE(sp)->moduleid = get_id (&sid, CIFF90DTYPE(sp)->moduleid);
03047                 for (i = 0; i < (int) CIFF90DTYPE(sp)->nmembs; i++)
03048                         CIFF90DTYPE(sp)->memids[i] = get_id (&sid, CIFF90DTYPE(sp)->memids[i]);
03049         }
03050 
03051         spp = patbl[CIF_F90_BEGIN_SCOPE].aptr;
03052         for (rcnt = 0; rcnt < patbl[CIF_F90_BEGIN_SCOPE].next; rcnt++) {
03053                 sp = *spp++;
03054                 CIFF90BS(sp)->symid = get_id (&sid, CIFF90BS(sp)->symid);
03055                 CIFF90BS(sp)->scopeid = get_id (&sid, CIFF90BS(sp)->scopeid);
03056                 CIFF90BS(sp)->parentid = get_id (&sid, CIFF90BS(sp)->parentid);
03057 #ifdef REMAP_FID
03058                 CIFF90BS(sp)->fid = get_id (&fid, CIFF90BS(sp)->fid);
03059 #endif
03060         }
03061 
03062         spp = patbl[CIF_F90_END_SCOPE].aptr;
03063         for (rcnt = 0; rcnt < patbl[CIF_F90_END_SCOPE].next; rcnt++) {
03064                 sp = *spp++;
03065                 CIFF90ES(sp)->scopeid = get_id (&sid, CIFF90ES(sp)->scopeid);
03066 #ifdef REMAP_FID
03067                 CIFF90ES(sp)->fid = get_id (&fid, CIFF90ES(sp)->fid);
03068 #endif
03069         }
03070 
03071         spp = patbl[CIF_F90_SCOPE_INFO].aptr;
03072         for (rcnt = 0; rcnt < patbl[CIF_F90_SCOPE_INFO].next; rcnt++) {
03073                 sp = *spp++;
03074                 CIFF90SI(sp)->scopeid = get_id (&sid, CIFF90SI(sp)->scopeid);
03075                 for (i = 0; i < (int) CIFF90SI(sp)->numalts; i++)
03076                         CIFF90SI(sp)->entryids[i] = get_id (&sid, CIFF90SI(sp)->entryids[i]);
03077         }
03078 
03079         spp = patbl[CIF_F90_USE_MODULE].aptr;
03080         for (rcnt = 0; rcnt < patbl[CIF_F90_USE_MODULE].next; rcnt++) {
03081                 sp = *spp++;
03082                 CIFF90USE(sp)->modid = get_id (&sid, CIFF90USE(sp)->modid);
03083 #ifdef REMAP_FID
03084                 CIFF90USE(sp)->modfid = get_id (&fid, CIFF90USE(sp)->modfid);
03085 #endif
03086         }
03087 
03088         spp = patbl[CIF_F90_RENAME].aptr;
03089         for (rcnt = 0; rcnt < patbl[CIF_F90_RENAME].next; rcnt++) {
03090                 sp = *spp++;
03091                 CIFF90RN(sp)->modid = get_id (&sid, CIFF90RN(sp)->modid);
03092                 CIFF90RN(sp)->origmodid = get_id (&sid, CIFF90RN(sp)->origmodid);
03093                 CIFF90RN(sp)->nameid = get_id (&sid, CIFF90RN(sp)->nameid);
03094                 CIFF90RN(sp)->scopeid = get_id (&sid, CIFF90RN(sp)->scopeid);
03095 
03096                 for (i = 0; i < (int) CIFF90RN(sp)->nlocalids; i++)
03097                     CIFF90RN(sp)->localid[i] =
03098                         get_id (&sid, CIFF90RN(sp)->localid[i]);
03099         }
03100 
03101         spp = patbl[CIF_F90_INT_BLOCK].aptr;
03102         for (rcnt = 0; rcnt < patbl[CIF_F90_INT_BLOCK].next; rcnt++) {
03103                 sp = *spp++;
03104                 CIFF90IB(sp)->intid = get_id (&sid, CIFF90IB(sp)->intid);
03105                 CIFF90IB(sp)->moduleid = get_id (&sid, CIFF90IB(sp)->moduleid);
03106                 CIFF90IB(sp)->scopeid = get_id (&sid, CIFF90IB(sp)->scopeid);
03107                 for (i = 0; i < (int) CIFF90IB(sp)->numints; i++)
03108                         CIFF90IB(sp)->procids[i] = get_id (&sid, CIFF90IB(sp)->procids[i]);
03109         }
03110 
03111 
03112         spp = patbl[CIF_C_TAG].aptr;
03113         for (rcnt = 0; rcnt < patbl[CIF_C_TAG].next; rcnt++) {
03114                 sp = *spp++;
03115                 CIFCTAG(sp)->tagid = get_id (&sid, CIFCTAG(sp)->tagid);
03116                 for (i = 0; i < (int) CIFCTAG(sp)->nmems; i++)
03117                         CIFCTAG(sp)->memids[i] = get_id (&sid, CIFCTAG(sp)->memids[i]);
03118         }
03119 
03120 #ifdef REMAP_FID
03121         spp = patbl[CIF_C_MESSAGE].aptr;
03122         for (rcnt = 0; rcnt < patbl[CIF_C_MESSAGE].next; rcnt++) {
03123                 sp = *spp++;
03124                 CIFCMSG(sp)->fid = get_id (&fid, CIFCMSG(sp)->fid);
03125                 CIFCMSG(sp)->incid = get_id (&fid, CIFCMSG(sp)->incid);
03126         }
03127 #endif
03128 
03129         spp = patbl[CIF_C_CONST].aptr;
03130         for (rcnt = 0; rcnt < patbl[CIF_C_CONST].next; rcnt++) {
03131                 sp = *spp++;
03132                 CIFCCON(sp)->symid = get_id (&sid, CIFCCON(sp)->symid);
03133         }
03134 
03135 
03136         spp = patbl[CIF_C_ENTRY].aptr;
03137         for (rcnt = 0; rcnt < patbl[CIF_C_ENTRY].next; rcnt++) {
03138                 sp = *spp++;
03139 
03140                 CIFCENTRY(sp)->symid = get_id (&sid, CIFCENTRY(sp)->symid);
03141                 CIFCENTRY(sp)->tagid = get_id (&sid, CIFCENTRY(sp)->tagid);
03142                 CIFCENTRY(sp)->link = get_id (&sid, CIFCENTRY(sp)->link);
03143 
03144                 for (i = 0; i < (int) CIFCENTRY(sp)->nargs; i++) {
03145                   CIFCENTRY(sp)->argids[i] = get_id (&sid, CIFCENTRY(sp)->argids[i]);
03146                 }
03147 
03148         }
03149 
03150 
03151         spp = patbl[CIF_C_OBJECT].aptr;
03152         for (rcnt = 0; rcnt < patbl[CIF_C_OBJECT].next; rcnt++) {
03153                 sp = *spp++;
03154                 CIFCOBJ(sp)->symid = get_id (&sid, CIFCOBJ(sp)->symid);
03155                 CIFCOBJ(sp)->psymid = get_id (&sid, CIFCOBJ(sp)->psymid);
03156                 CIFCOBJ(sp)->tagid = get_id (&sid, CIFCOBJ(sp)->tagid);
03157                 CIFCOBJ(sp)->link = get_id (&sid, CIFCOBJ(sp)->link);
03158         }
03159 
03160 
03161         spp = patbl[CIF_C_LINT_DIRECTIVE].aptr;
03162         for (rcnt = 0; rcnt < patbl[CIF_C_LINT_DIRECTIVE].next; rcnt++) {
03163                 sp = *spp++;
03164                 CIFCLDIR(sp)->objid = get_id (&sid, CIFCLDIR(sp)->objid);
03165 #ifdef REMAP_FID
03166                 CIFCLDIR(sp)->fid = get_id (&fid, CIFCLDIR(sp)->fid);
03167 #endif
03168         }
03169 
03170         spp = patbl[CIF_C_MACRO_DEF].aptr;
03171         for (rcnt = 0; rcnt < patbl[CIF_C_MACRO_DEF].next; rcnt++) {
03172                 sp = *spp++;
03173                 CIFCMDEF(sp)->symid = get_id (&sid, CIFCMDEF(sp)->symid);
03174 #ifdef REMAP_FID
03175                 CIFCMDEF(sp)->fid = get_id (&fid, CIFCMDEF(sp)->fid);
03176 #endif
03177         }
03178 
03179         spp = patbl[CIF_C_MACRO_UNDEF].aptr;
03180         for (rcnt = 0; rcnt < patbl[CIF_C_MACRO_UNDEF].next; rcnt++) {
03181                 sp = *spp++;
03182                 CIFCMUDEF(sp)->symid = get_id (&sid, CIFCMUDEF(sp)->symid);
03183 #ifdef REMAP_FID
03184                 CIFCMUDEF(sp)->fid = get_id (&fid, CIFCMUDEF(sp)->fid);
03185 #endif
03186         }
03187 
03188 
03189 
03190         spp = patbl[CIF_C_MACRO_USAGE].aptr;
03191         for (rcnt = 0; rcnt < patbl[CIF_C_MACRO_USAGE].next; rcnt++) {
03192                 sp = *spp++;
03193                 CIFCMUSE(sp)->symid = get_id (&sid, CIFCMUSE(sp)->symid);
03194 #ifdef REMAP_FID
03195                 CIFCMUSE(sp)->fid = get_id (&fid, CIFCMUSE(sp)->fid);
03196 #endif
03197         }
03198 
03199         spp = patbl[CIF_C_ENTRY_END].aptr;
03200         for (rcnt = 0; rcnt < patbl[CIF_C_ENTRY_END].next; rcnt++) {
03201                 sp = *spp++;
03202                 CIFCEEND(sp)->symid = get_id (&sid, CIFCEEND(sp)->symid);
03203 #ifdef REMAP_FID
03204                 CIFCEEND(sp)->fid = get_id (&fid, CIFCEEND(sp)->fid);
03205 #endif
03206         }
03207 
03208 
03209         spp = patbl[CIF_CC_TYPE].aptr;
03210         for (rcnt = 0; rcnt < patbl[CIF_CC_TYPE].next; rcnt++) {
03211             sp = *spp++;
03212             CIFCCTYPE(sp)->symid = get_id (&sid, CIFCCTYPE(sp)->symid);
03213             CIFCCTYPE(sp)->scopeid = get_id (&sid, CIFCCTYPE(sp)->scopeid);
03214             j = CIFCCTYPE(sp)->nmem;
03215             for (i = 0; i < j; i++ ) {
03216                 CIFCCTYPE(sp)->mem[i] = get_id (&sid, CIFCCTYPE(sp)->mem[i]);
03217             }
03218         }
03219 
03220         spp = patbl[CIF_CC_ENTRY].aptr;
03221         for (rcnt = 0; rcnt < patbl[CIF_CC_ENTRY].next; rcnt++) {
03222             sp = *spp++;
03223             CIFCCENT(sp)->symid = get_id (&sid, CIFCCENT(sp)->symid);
03224             CIFCCENT(sp)->fsymid = get_id (&sid, CIFCCENT(sp)->fsymid);
03225             CIFCCENT(sp)->scopeid = get_id (&sid, CIFCCENT(sp)->scopeid);
03226 #ifdef REMAP_FID
03227             CIFCCENT(sp)->sfid = get_id (&fid, CIFCCENT(sp)->sfid);
03228             CIFCCENT(sp)->efid = get_id (&fid, CIFCCENT(sp)->efid);
03229 #endif
03230             j = CIFCCENT(sp)->nparam;
03231             for (i = 0; i < j; i++ ) {
03232                 CIFCCENT(sp)->param[i] = get_id (&sid, CIFCCENT(sp)->param[i]);
03233             }
03234         }
03235 
03236         spp = patbl[CIF_CC_OBJ].aptr;
03237         for (rcnt = 0; rcnt < patbl[CIF_CC_OBJ].next; rcnt++) {
03238             sp = *spp++;
03239             CIFCCOBJ(sp)->symid = get_id (&sid, CIFCCOBJ(sp)->symid);
03240             CIFCCOBJ(sp)->scopeid = get_id (&sid, CIFCCOBJ(sp)->scopeid);
03241         }
03242 
03243         spp = patbl[CIF_CC_SUBTYPE].aptr;
03244         for (rcnt = 0; rcnt < patbl[CIF_CC_SUBTYPE].next; rcnt++) {
03245             sp = *spp++;
03246             CIFCCSUB(sp)->symid = get_id (&sid, CIFCCSUB(sp)->symid);
03247         }
03248 
03249         spp = patbl[CIF_CC_ENUM].aptr;
03250         for (rcnt = 0; rcnt < patbl[CIF_CC_ENUM].next; rcnt++) {
03251             sp = *spp++;
03252             CIFCCENUM(sp)->symid = get_id (&sid, CIFCCENUM(sp)->symid);
03253         }
03254 
03255 #ifdef REMAP_FID
03256         spp = patbl[CIF_CC_EXPR].aptr;
03257         for (rcnt = 0; rcnt < patbl[CIF_CC_EXPR].next; rcnt++) {
03258             sp = *spp++;
03259             CIFCCEXPR(sp)->fid = get_id (&fid, CIFCCEXPR(sp)->fid);
03260         }
03261 #endif
03262 
03263 
03264 #ifdef REMAP_FID
03265         spp = patbl[CIF_BE_NODE].aptr;
03266         for (rcnt = 0; rcnt < patbl[CIF_BE_NODE].next; rcnt++) {
03267             sp = *spp++;
03268             j = CIFBENODE(sp)->nlines;
03269             for (i = 0; i < j; i++ ) {
03270                 CIFBENODE(sp)->fid[i] = get_id (&fid, CIFBENODE(sp)->fid[i]);
03271             }
03272         }
03273 
03274         spp = patbl[CIF_BE_FID].aptr;
03275         for (rcnt = 0; rcnt < patbl[CIF_BE_FID].next; rcnt++) {
03276             sp = *spp++;
03277             j = CIFBEFID(sp)->nfid;
03278             for (i = 0; i < j; i++ ) {
03279                 CIFBEFID(sp)->fid[i] = get_id (&fid, CIFBEFID(sp)->fid[i]);
03280             }
03281         }
03282 #endif
03283 
03284 }
03285 
03286 
03287 /* --------------------------------------------------------------------------
03288  * get_max_sid scans the patbl contents for the current unit and determines
03289  * what the largest symbol id value is.
03290  * --------------------------------------------------------------------------
03291  */
03292 static long get_max_sid (void)
03293 {
03294 
03295         struct Cif_generic **spp;       
03296         int rcnt;
03297         long sid, maxsid = 0;
03298 
03299         spp = patbl[CIF_COMBLK].aptr;
03300         for (rcnt = 0; rcnt < patbl[CIF_COMBLK].next; rcnt++) {
03301                 if ((sid = CIFCB(*spp++)->symid) > maxsid)
03302                         maxsid = sid;
03303         }
03304 
03305         spp = patbl[CIF_CONST].aptr;
03306         for (rcnt = 0; rcnt < patbl[CIF_CONST].next; rcnt++) {
03307                 if ((sid = CIFCON(*spp++)->symid) > maxsid)
03308                         maxsid = sid;
03309         }
03310 
03311         spp = patbl[CIF_ENTRY].aptr;
03312         for (rcnt = 0; rcnt < patbl[CIF_ENTRY].next; rcnt++) {
03313                 if ((sid = CIFENTRY(*spp++)->symid) > maxsid)
03314                         maxsid = sid;
03315         }
03316 
03317         spp = patbl[CIF_LABEL].aptr;
03318         for (rcnt = 0; rcnt < patbl[CIF_LABEL].next; rcnt++) {
03319                 if ((sid = CIFLABEL(*spp++)->symid) > maxsid)
03320                         maxsid = sid;
03321         }
03322 
03323         spp = patbl[CIF_NAMELIST].aptr;
03324         for (rcnt = 0; rcnt < patbl[CIF_NAMELIST].next; rcnt++) {
03325                 if ((sid = CIFNL(*spp++)->symid) > maxsid)
03326                         maxsid = sid;
03327         }
03328 
03329         spp = patbl[CIF_OBJECT].aptr;
03330         for (rcnt = 0; rcnt < patbl[CIF_OBJECT].next; rcnt++) {
03331                 if ((sid = CIFOBJ(*spp++)->symid) > maxsid)
03332                         maxsid = sid;
03333         }
03334 
03335         spp = patbl[CIF_F90_COMBLK].aptr;
03336         for (rcnt = 0; rcnt < patbl[CIF_F90_COMBLK].next; rcnt++) {
03337                 if ((sid = CIFF90CB(*spp++)->symid) > maxsid)
03338                         maxsid = sid;
03339         }
03340 
03341         spp = patbl[CIF_F90_CONST].aptr;
03342         for (rcnt = 0; rcnt < patbl[CIF_F90_CONST].next; rcnt++) {
03343                 if ((sid = CIFF90CON(*spp++)->symid) > maxsid)
03344                         maxsid = sid;
03345         }
03346 
03347         spp = patbl[CIF_F90_ENTRY].aptr;
03348         for (rcnt = 0; rcnt < patbl[CIF_F90_ENTRY].next; rcnt++) {
03349                 if ((sid = CIFF90ENTRY(*spp++)->symid) > maxsid)
03350                         maxsid = sid;
03351         }
03352 
03353         spp = patbl[CIF_F90_LABEL].aptr;
03354         for (rcnt = 0; rcnt < patbl[CIF_F90_LABEL].next; rcnt++) {
03355                 if ((sid = CIFF90LABEL(*spp++)->symid) > maxsid)
03356                         maxsid = sid;
03357         }
03358 
03359         spp = patbl[CIF_F90_NAMELIST].aptr;
03360         for (rcnt = 0; rcnt < patbl[CIF_F90_NAMELIST].next; rcnt++) {
03361                 if ((sid = CIFF90NL(*spp++)->symid) > maxsid)
03362                         maxsid = sid;
03363         }
03364 
03365         spp = patbl[CIF_F90_OBJECT].aptr;
03366         for (rcnt = 0; rcnt < patbl[CIF_F90_OBJECT].next; rcnt++) {
03367                 if ((sid = CIFF90OBJ(*spp++)->symid) > maxsid)
03368                         maxsid = sid;
03369         }
03370 
03371         spp = patbl[CIF_F90_BEGIN_SCOPE].aptr;
03372         for (rcnt = 0; rcnt < patbl[CIF_F90_BEGIN_SCOPE].next; rcnt++) {
03373                 if ((sid = CIFF90BS(*spp++)->scopeid) > maxsid)
03374                         maxsid = sid;
03375         }
03376 
03377         spp = patbl[CIF_GEOMETRY].aptr;
03378         for (rcnt = 0; rcnt < patbl[CIF_GEOMETRY].next; rcnt++) {
03379                 if ((sid = CIFGEOM(*spp++)->geomid) > maxsid)
03380                         maxsid = sid;
03381         }
03382 
03383 
03384         spp = patbl[CIF_C_CONST].aptr;
03385         for (rcnt = 0; rcnt < patbl[CIF_C_CONST].next; rcnt++) {
03386                 if ((sid = CIFCCON(*spp++)->symid) > maxsid)
03387                         maxsid = sid;
03388         }
03389 
03390         spp = patbl[CIF_C_ENTRY].aptr;
03391         for (rcnt = 0; rcnt < patbl[CIF_C_ENTRY].next; rcnt++) {
03392                 if ((sid = CIFCENTRY(*spp++)->symid) > maxsid)
03393                         maxsid = sid;
03394         }
03395 
03396         spp = patbl[CIF_C_OBJECT].aptr;
03397         for (rcnt = 0; rcnt < patbl[CIF_C_OBJECT].next; rcnt++) {
03398                 if ((sid = CIFCOBJ(*spp++)->symid) > maxsid)
03399                         maxsid = sid;
03400         }
03401 
03402         spp = patbl[CIF_C_LINT_DIRECTIVE].aptr;
03403         for (rcnt = 0; rcnt < patbl[CIF_C_LINT_DIRECTIVE].next; rcnt++) {
03404                 if ((sid = CIFCLDIR(*spp++)->objid) > maxsid)
03405                         maxsid = sid;
03406         }
03407 
03408         spp = patbl[CIF_C_MACRO_DEF].aptr;
03409         for (rcnt = 0; rcnt < patbl[CIF_C_MACRO_DEF].next; rcnt++) {
03410                 if ((sid = CIFCMDEF(*spp++)->symid) > maxsid)
03411                         maxsid = sid;
03412         }
03413 
03414         spp = patbl[CIF_C_TAG].aptr;
03415         for (rcnt = 0; rcnt < patbl[CIF_C_TAG].next; rcnt++) {
03416                 if ((sid = CIFCTAG(*spp++)->tagid) > maxsid)
03417                         maxsid = sid;
03418         }
03419 
03420         return (maxsid);
03421 }
03422 
03423 #ifdef REMAP_FID
03424 /* --------------------------------------------------------------------------
03425  * remap_files scans the patbl contents for the all non-unit records that
03426  * contain file id values.  remap_files collects all the file ids, sorts 'em,
03427  * and then changes the file ids to new values.
03428  * --------------------------------------------------------------------------
03429  */
03430 static void remap_files (
03431         void)
03432 {
03433         struct Cif_generic *sp, **spp;
03434         int rcnt;
03435 
03436         init_id (&fid);
03437 
03438         spp = patbl[CIF_FILE].aptr;
03439         for (rcnt = 0; rcnt < patbl[CIF_FILE].next; rcnt++) {
03440                 add_id (&fid, CIFFILE(*spp++)->fid);
03441         }
03442 
03443         (void) qsort ((char *)fid.tbl, fid.cur, sizeof(long), (int(*)()) comp_ids);
03444 
03445         spp = patbl[CIF_FILE].aptr;
03446         for (rcnt = 0; rcnt < patbl[CIF_FILE].next; rcnt++) {
03447                 sp = *spp++;
03448                 CIFFILE(sp)->fid = get_id (&fid, CIFFILE(sp)->fid);
03449         }
03450 
03451         spp = patbl[CIF_INCLUDE].aptr;
03452         for (rcnt = 0; rcnt < patbl[CIF_INCLUDE].next; rcnt++) {
03453                 sp = *spp++;
03454                 CIFINC(sp)->srcid = get_id (&fid, CIFINC(sp)->srcid);
03455                 CIFINC(sp)->incid = get_id (&fid, CIFINC(sp)->incid);
03456         }
03457 
03458         spp = patbl[CIF_SRCFILE].aptr;
03459         for (rcnt = 0; rcnt < patbl[CIF_SRCFILE].next; rcnt++) {
03460                 sp = *spp++;
03461                 CIFSRC(sp)->fid = get_id (&fid, CIFSRC(sp)->fid);
03462                 srcfid = CIFSRC(sp)->fid;
03463         }
03464 
03465         spp = patbl[CIF_SRC_POS].aptr;
03466         for (rcnt = 0; rcnt < patbl[CIF_SRC_POS].next; rcnt++) {
03467                 sp = *spp++;
03468                 CIFSPOS(sp)->srcid  = get_id (&fid, CIFSPOS(sp)->srcid);
03469                 CIFSPOS(sp)->psrcid = get_id (&fid, CIFSPOS(sp)->psrcid);
03470                 CIFSPOS(sp)->fid    = get_id (&fid, CIFSPOS(sp)->fid);
03471         }
03472 }
03473 #endif
03474 
03475 /* --------------------------------------------------------------------------
03476  * get_max_fid scans the patbl contents for the file records and locates
03477  * the largest id value.
03478  * --------------------------------------------------------------------------
03479  */
03480 static long get_max_fid (
03481         void)
03482 {
03483 
03484         struct Cif_generic **spp;
03485         int rcnt;
03486         long fid, maxfid = 0;
03487 
03488         spp = patbl[CIF_FILE].aptr;
03489         for (rcnt = 0; rcnt < patbl[CIF_FILE].next; rcnt++) {
03490                 if ((fid = CIFFILE(*spp++)->fid) > maxfid)
03491                         maxfid = fid;
03492         }
03493 
03494         return (maxfid);
03495 }
03496 
03497 

Generated on Tue Nov 17 05:54:41 2009 for Open64 (mfef90, whirl2f, and IR tools) by  doxygen 1.6.1