Back to home page

MITgcm

 
 

    


File indexing completed on 2018-03-02 18:44:43 UTC

view on githubraw file Latest commit bf5846c3 on 2004-02-25 18:19:54 UTC
bf5846c3a1 Ed H*0001 /* $XConsortium: include.c,v 1.16 94/04/17 20:10:34 gildea Exp $ */
                0002 
                0003 /*
                0004  * Copyright (c) 1998-2003 Carnegie Mellon University.  All rights reserved.
                0005  *
                0006  * Redistribution and use in source and binary forms, with or without
                0007  * modification, are permitted provided that the following conditions
                0008  * are met:
                0009  *
                0010  * 1. Redistributions of source code must retain the above copyright
                0011  *    notice, this list of conditions and the following disclaimer. 
                0012  *
                0013  * 2. Redistributions in binary form must reproduce the above copyright
                0014  *    notice, this list of conditions and the following disclaimer in
                0015  *    the documentation and/or other materials provided with the
                0016  *    distribution.
                0017  *
                0018  * 3. The name "Carnegie Mellon University" must not be used to
                0019  *    endorse or promote products derived from this software without
                0020  *    prior written permission. For permission or any other legal
                0021  *    details, please contact  
                0022  *      Office of Technology Transfer
                0023  *      Carnegie Mellon University
                0024  *      5000 Forbes Avenue
                0025  *      Pittsburgh, PA  15213-3890
                0026  *      (412) 268-4387, fax: (412) 268-7395
                0027  *      tech-transfer@andrew.cmu.edu
                0028  *
                0029  * 4. Redistributions of any form whatsoever must retain the following
                0030  *    acknowledgment:
                0031  *    "This product includes software developed by Computing Services
                0032  *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
                0033  *
                0034  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
                0035  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
                0036  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
                0037  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                0038  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
                0039  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
                0040  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                0041  *
                0042  */
                0043 /*
                0044 
                0045 Copyright (c) 1993, 1994  X Consortium
                0046 
                0047 Permission is hereby granted, free of charge, to any person obtaining a copy
                0048 of this software and associated documentation files (the "Software"), to deal
                0049 in the Software without restriction, including without limitation the rights
                0050 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                0051 copies of the Software, and to permit persons to whom the Software is
                0052 furnished to do so, subject to the following conditions:
                0053 
                0054 The above copyright notice and this permission notice shall be included in
                0055 all copies or substantial portions of the Software.
                0056 
                0057 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                0058 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                0059 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
                0060 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
                0061 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
                0062 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
                0063 
                0064 Except as contained in this notice, the name of the X Consortium shall not be
                0065 used in advertising or otherwise to promote the sale, use or other dealings
                0066 in this Software without prior written authorization from the X Consortium.
                0067 
                0068 */
                0069 
                0070 
                0071 #include "def.h"
                0072 
                0073 extern struct   inclist inclist[ MAXFILES ],
                0074             *inclistp;
                0075 extern char *includedirs[ ];
                0076 extern char *notdotdot[ ];
                0077 extern boolean show_where_not;
                0078 extern boolean warn_multiple;
                0079 
                0080 struct inclist *inc_path(file, include, dot)
                0081     register char   *file,
                0082             *include;
                0083     boolean dot;
                0084 {
                0085     static char path[ BUFSIZ ];
                0086     register char       **pp, *p;
                0087     register struct inclist *ip;
                0088     struct stat st;
                0089     boolean found = FALSE;
                0090 
                0091     /*
                0092      * Check all previously found include files for a path that
                0093      * has already been expanded.
                0094      */
                0095     for (ip = inclist; ip->i_file; ip++)
                0096         if ((strcmp(ip->i_incstring, include) == 0) && !ip->i_included_sym)
                0097         {
                0098         found = TRUE;
                0099         break;
                0100         }
                0101 
                0102     /*
                0103      * If the path was surrounded by "" or is an absolute path,
                0104      * then check the exact path provided.
                0105      */
                0106     if (!found && (dot || *include == '/')) {
                0107         if (stat(include, &st) == 0) {
                0108             ip = newinclude(include, include);
                0109             found = TRUE;
                0110         }
                0111         else if (show_where_not)
                0112             warning1("\tnot in %s\n", include);
                0113     }
                0114 
                0115     /*
                0116      * See if this include file is in the directory of the
                0117      * file being compiled.
                0118      */
                0119     if (!found) {
                0120         for (p=file+strlen(file); p>file; p--)
                0121             if (*p == '/')
                0122                 break;
                0123         if (p == file)
                0124             strcpy(path, include);
                0125         else {
                0126             strncpy(path, file, (p-file) + 1);
                0127             path[ (p-file) + 1 ] = '\0';
                0128             strcpy(path + (p-file) + 1, include);
                0129         }
                0130         remove_dotdot(path);
                0131         if (stat(path, &st) == 0) {
                0132             ip = newinclude(path, include);
                0133             found = TRUE;
                0134         }
                0135         else if (show_where_not)
                0136             warning1("\tnot in %s\n", path);
                0137     }
                0138 
                0139     /*
                0140      * Check the include directories specified. (standard include dir
                0141      * should be at the end.)
                0142      */
                0143     if (!found)
                0144         for (pp = includedirs; *pp; pp++) {
                0145             sprintf(path, "%s/%s", *pp, include);
                0146             remove_dotdot(path);
                0147             if (stat(path, &st) == 0) {
                0148                 ip = newinclude(path, include);
                0149                 found = TRUE;
                0150                 break;
                0151             }
                0152             else if (show_where_not)
                0153                 warning1("\tnot in %s\n", path);
                0154         }
                0155 
                0156     if (!found)
                0157         ip = NULL;
                0158     return(ip);
                0159 }
                0160 
                0161 /*
                0162  * Ocaisionally, pathnames are created that look like ../x/../y
                0163  * Any of the 'x/..' sequences within the name can be eliminated.
                0164  * (but only if 'x' is not a symbolic link!!)
                0165  */
                0166 remove_dotdot(path)
                0167     char    *path;
                0168 {
                0169     register char   *end, *from, *to, **cp;
                0170     char        *components[ MAXFILES ],
                0171             newpath[ BUFSIZ ];
                0172     boolean     component_copied;
                0173 
                0174     /*
                0175      * slice path up into components.
                0176      */
                0177     to = newpath;
                0178     if (*path == '/')
                0179         *to++ = '/';
                0180     *to = '\0';
                0181     cp = components;
                0182     for (from=end=path; *end; end++)
                0183         if (*end == '/') {
                0184             while (*end == '/')
                0185                 *end++ = '\0';
                0186             if (*from)
                0187                 *cp++ = from;
                0188             from = end;
                0189         }
                0190     *cp++ = from;
                0191     *cp = NULL;
                0192 
                0193     /*
                0194      * Now copy the path, removing all 'x/..' components.
                0195      */
                0196     cp = components;
                0197     component_copied = FALSE;
                0198     while(*cp) {
                0199         if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))) {
                0200             if (issymbolic(newpath, *cp))
                0201                 goto dont_remove;
                0202             cp++;
                0203         } else {
                0204         dont_remove:
                0205             if (component_copied)
                0206                 *to++ = '/';
                0207             component_copied = TRUE;
                0208             for (from = *cp; *from; )
                0209                 *to++ = *from++;
                0210             *to = '\0';
                0211         }
                0212         cp++;
                0213     }
                0214     *to++ = '\0';
                0215 
                0216     /*
                0217      * copy the reconstituted path back to our pointer.
                0218      */
                0219     strcpy(path, newpath);
                0220 }
                0221 
                0222 isdot(p)
                0223     register char   *p;
                0224 {
                0225     if(p && *p++ == '.' && *p++ == '\0')
                0226         return(TRUE);
                0227     return(FALSE);
                0228 }
                0229 
                0230 isdotdot(p)
                0231     register char   *p;
                0232 {
                0233     if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
                0234         return(TRUE);
                0235     return(FALSE);
                0236 }
                0237 
                0238 issymbolic(dir, component)
                0239     register char   *dir, *component;
                0240 {
                0241 #ifdef S_IFLNK
                0242     struct stat st;
                0243     char    buf[ BUFSIZ ], **pp;
                0244 
                0245     sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component);
                0246     for (pp=notdotdot; *pp; pp++)
                0247         if (strcmp(*pp, buf) == 0)
                0248             return (TRUE);
                0249     if (lstat(buf, &st) == 0
                0250     && (st.st_mode & S_IFMT) == S_IFLNK) {
                0251         *pp++ = copy(buf);
                0252         if (pp >= &notdotdot[ MAXDIRS ])
                0253             fatalerr("out of .. dirs, increase MAXDIRS\n");
                0254         return(TRUE);
                0255     }
                0256 #endif
                0257     return(FALSE);
                0258 }
                0259 
                0260 /*
                0261  * Add an include file to the list of those included by 'file'.
                0262  */
                0263 struct inclist *newinclude(newfile, incstring)
                0264     register char   *newfile, *incstring;
                0265 {
                0266     register struct inclist *ip;
                0267 
                0268     /*
                0269      * First, put this file on the global list of include files.
                0270      */
                0271     ip = inclistp++;
                0272     if (inclistp == inclist + MAXFILES - 1)
                0273         fatalerr("out of space: increase MAXFILES\n");
                0274     ip->i_file = copy(newfile);
                0275     ip->i_included_sym = FALSE;
                0276     if (incstring == NULL)
                0277         ip->i_incstring = ip->i_file;
                0278     else
                0279         ip->i_incstring = copy(incstring);
                0280 
                0281     return(ip);
                0282 }
                0283 
                0284 included_by(ip, newfile)
                0285     register struct inclist *ip, *newfile;
                0286 {
                0287     register i;
                0288 
                0289     if (ip == NULL)
                0290         return;
                0291     /*
                0292      * Put this include file (newfile) on the list of files included
                0293      * by 'file'.  If 'file' is NULL, then it is not an include
                0294      * file itself (i.e. was probably mentioned on the command line).
                0295      * If it is already on the list, don't stick it on again.
                0296      */
                0297     if (ip->i_list == NULL)
                0298         ip->i_list = (struct inclist **)
                0299             malloc(sizeof(struct inclist *) * ++ip->i_listlen);
                0300     else {
                0301         for (i=0; i<ip->i_listlen; i++)
                0302             if (ip->i_list[ i ] == newfile) {
                0303                 i = strlen(newfile->i_file);
                0304                 if (!ip->i_included_sym &&
                0305                 !(i > 2 &&
                0306                   newfile->i_file[i-1] == 'c' &&
                0307                   newfile->i_file[i-2] == '.'))
                0308                 {
                0309                 /* only bitch if ip has */
                0310                 /* no #include SYMBOL lines  */
                0311                 /* and is not a .c file */
                0312                 if (warn_multiple)
                0313                 {
                0314                     warning("%s includes %s more than once!\n",
                0315                         ip->i_file, newfile->i_file);
                0316                     warning1("Already have\n");
                0317                     for (i=0; i<ip->i_listlen; i++)
                0318                         warning1("\t%s\n", ip->i_list[i]->i_file);
                0319                 }
                0320                 }
                0321                 return;
                0322             }
                0323         ip->i_list = (struct inclist **) realloc(ip->i_list,
                0324             sizeof(struct inclist *) * ++ip->i_listlen);
                0325     }
                0326     ip->i_list[ ip->i_listlen-1 ] = newfile;
                0327 }
                0328 
                0329 inc_clean ()
                0330 {
                0331     register struct inclist *ip;
                0332 
                0333     for (ip = inclist; ip < inclistp; ip++) {
                0334         ip->i_marked = FALSE;
                0335     }
                0336 }