00001 /****************************************************************************** 00002 * $Id: cpl_findfile_cpp-source.html,v 1.13 2002/12/21 19:13:12 warmerda Exp $ 00003 * 00004 * Project: CPL - Common Portability Library 00005 * Purpose: Generic data file location finder, with application hooking. 00006 * Author: Frank Warmerdam, warmerda@home.com 00007 * 00008 ****************************************************************************** 00009 * Copyright (c) 2000, Frank Warmerdam 00010 * 00011 * Permission is hereby granted, free of charge, to any person obtaining a 00012 * copy of this software and associated documentation files (the "Software"), 00013 * to deal in the Software without restriction, including without limitation 00014 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00015 * and/or sell copies of the Software, and to permit persons to whom the 00016 * Software is furnished to do so, subject to the following conditions: 00017 * 00018 * The above copyright notice and this permission notice shall be included 00019 * in all copies or substantial portions of the Software. 00020 * 00021 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00022 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00023 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00024 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00025 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00026 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00027 * DEALINGS IN THE SOFTWARE. 00028 ****************************************************************************** 00029 * 00030 * $Log: cpl_findfile_cpp-source.html,v $ 00030 * Revision 1.13 2002/12/21 19:13:12 warmerda 00030 * updated 00030 * 00031 * Revision 1.4 2002/12/03 04:42:02 warmerda 00032 * improved finder cleanup support 00033 * 00034 * Revision 1.3 2001/07/18 04:00:49 warmerda 00035 * added CPL_CVSID 00036 * 00037 * Revision 1.2 2001/01/19 21:16:41 warmerda 00038 * expanded tabs 00039 * 00040 * Revision 1.1 2000/08/29 21:06:25 warmerda 00041 * New 00042 * 00043 */ 00044 00045 #include "cpl_conv.h" 00046 #include "cpl_string.h" 00047 00048 CPL_CVSID("$Id: cpl_findfile_cpp-source.html,v 1.13 2002/12/21 19:13:12 warmerda Exp $"); 00049 00050 static int bFinderInitialized = FALSE; 00051 static int nFileFinders = 0; 00052 static CPLFileFinder *papfnFinders = NULL; 00053 static char **papszFinderLocations = NULL; 00054 00055 /************************************************************************/ 00056 /* CPLFinderInit() */ 00057 /************************************************************************/ 00058 00059 static void CPLFinderInit() 00060 00061 { 00062 if( !bFinderInitialized ) 00063 { 00064 bFinderInitialized = TRUE; 00065 CPLPushFileFinder( CPLDefaultFindFile ); 00066 CPLPushFinderLocation( "/usr/local/share" ); 00067 CPLPushFinderLocation( "." ); 00068 } 00069 } 00070 00071 /************************************************************************/ 00072 /* CPLFinderClean() */ 00073 /************************************************************************/ 00074 00075 void CPLFinderClean() 00076 00077 { 00078 while( CPLPopFileFinder() != NULL ) {} 00079 while( papszFinderLocations != NULL ) 00080 CPLPopFinderLocation(); 00081 00082 bFinderInitialized = FALSE; 00083 } 00084 00085 /************************************************************************/ 00086 /* CPLDefaultFileFind() */ 00087 /************************************************************************/ 00088 00089 const char *CPLDefaultFindFile( const char *pszClass, 00090 const char *pszBasename ) 00091 00092 { 00093 int i, nLocations = CSLCount( papszFinderLocations ); 00094 00095 (void) pszClass; 00096 00097 for( i = nLocations-1; nLocations >= 0; nLocations-- ) 00098 { 00099 const char *pszResult; 00100 VSIStatBuf sStat; 00101 00102 pszResult = CPLFormFilename( papszFinderLocations[i], pszBasename, 00103 NULL ); 00104 00105 if( VSIStat( pszResult, &sStat ) == 0 ) 00106 return pszResult; 00107 } 00108 00109 return NULL; 00110 } 00111 00112 /************************************************************************/ 00113 /* CPLFindFile() */ 00114 /************************************************************************/ 00115 00116 const char *CPLFindFile( const char *pszClass, const char *pszBasename ) 00117 00118 { 00119 int i; 00120 00121 CPLFinderInit(); 00122 00123 for( i = nFileFinders-1; i >= 0; i-- ) 00124 { 00125 const char * pszResult; 00126 00127 pszResult = (papfnFinders[i])( pszClass, pszBasename ); 00128 if( pszResult != NULL ) 00129 return pszResult; 00130 } 00131 00132 return NULL; 00133 } 00134 00135 /************************************************************************/ 00136 /* CPLPushFileFinder() */ 00137 /************************************************************************/ 00138 00139 void CPLPushFileFinder( CPLFileFinder pfnFinder ) 00140 00141 { 00142 CPLFinderInit(); 00143 00144 papfnFinders = (CPLFileFinder *) 00145 CPLRealloc(papfnFinders, sizeof(void*) * ++nFileFinders); 00146 papfnFinders[nFileFinders-1] = pfnFinder; 00147 } 00148 00149 /************************************************************************/ 00150 /* CPLPopFileFinder() */ 00151 /************************************************************************/ 00152 00153 CPLFileFinder CPLPopFileFinder() 00154 00155 { 00156 CPLFileFinder pfnReturn; 00157 00158 CPLFinderInit(); 00159 00160 if( nFileFinders == 0 ) 00161 return NULL; 00162 00163 pfnReturn = papfnFinders[--nFileFinders]; 00164 00165 if( nFileFinders == 0) 00166 { 00167 CPLFree( papfnFinders ); 00168 papfnFinders = NULL; 00169 } 00170 00171 return pfnReturn; 00172 } 00173 00174 /************************************************************************/ 00175 /* CPLPushFinderLocation() */ 00176 /************************************************************************/ 00177 00178 void CPLPushFinderLocation( const char *pszLocation ) 00179 00180 { 00181 CPLFinderInit(); 00182 00183 papszFinderLocations = CSLAddString( papszFinderLocations, 00184 pszLocation ); 00185 } 00186 00187 00188 /************************************************************************/ 00189 /* CPLPopFinderLocation() */ 00190 /************************************************************************/ 00191 00192 void CPLPopFinderLocation() 00193 00194 { 00195 int nCount; 00196 00197 CPLFinderInit(); 00198 00199 nCount = CSLCount(papszFinderLocations); 00200 if( nCount == 0 ) 00201 return; 00202 00203 CPLFree( papszFinderLocations[nCount-1] ); 00204 papszFinderLocations[nCount-1] = NULL; 00205 00206 if( nCount == 1 ) 00207 { 00208 CPLFree( papszFinderLocations ); 00209 papszFinderLocations = NULL; 00210 } 00211 }