PageRenderTime 30ms CodeModel.GetById 20ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 0ms

/Proj4/pj_open_lib.c

http://github.com/route-me/route-me
C | 195 lines | 120 code | 13 blank | 62 comment | 6 complexity | daeb2da0bdfdc0fa7efdaa416bc5437a MD5 | raw file
  1/******************************************************************************
  2 * $Id: pj_open_lib.c,v 1.9 2007/07/06 14:58:03 fwarmerdam Exp $
  3 *
  4 * Project:  PROJ.4
  5 * Purpose:  Implementation of pj_open_lib(), and pj_set_finder().  These
  6 *           provide a standard interface for opening projections support
  7 *           data files.
  8 * Author:   Gerald Evenden, Frank Warmerdam <warmerdam@pobox.com>
  9 *
 10 ******************************************************************************
 11 * Copyright (c) 1995, Gerald Evenden
 12 * Copyright (c) 2002, Frank Warmerdam <warmerdam@pobox.com>
 13 *
 14 * Permission is hereby granted, free of charge, to any person obtaining a
 15 * copy of this software and associated documentation files (the "Software"),
 16 * to deal in the Software without restriction, including without limitation
 17 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 18 * and/or sell copies of the Software, and to permit persons to whom the
 19 * Software is furnished to do so, subject to the following conditions:
 20 *
 21 * The above copyright notice and this permission notice shall be included
 22 * in all copies or substantial portions of the Software.
 23 *
 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 25 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 27 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 30 * DEALINGS IN THE SOFTWARE.
 31 ******************************************************************************
 32 *
 33 * $Log: pj_open_lib.c,v $
 34 * Revision 1.9  2007/07/06 14:58:03  fwarmerdam
 35 * improve searchpath clearning with pj_set_searchpath()
 36 *
 37 * Revision 1.8  2007/03/11 17:03:18  fwarmerdam
 38 * support drive letter prefixes on win32 and related fixes (bug 1499)
 39 *
 40 * Revision 1.7  2006/11/17 22:16:30  mloskot
 41 * Uploaded PROJ.4 port for Windows CE.
 42 *
 43 * Revision 1.6  2004/09/16 15:14:01  fwarmerdam
 44 * * src/pj_open_lib.c: added pj_set_searchpath() provided by Eric Miller.
 45 *
 46 * Revision 1.5  2002/12/14 20:15:30  warmerda
 47 * updated headers
 48 *
 49 */
 50
 51#define PJ_LIB__
 52#include "projects.h"
 53#include <stdio.h>
 54#include <string.h>
 55#include <errno.h>
 56
 57PJ_CVSID("$Id: pj_open_lib.c,v 1.9 2007/07/06 14:58:03 fwarmerdam Exp $");
 58
 59static const char *(*pj_finder)(const char *) = NULL;
 60static int path_count = 0;
 61static char **search_path = NULL;
 62static char * proj_lib_name =
 63#ifdef PROJ_LIB
 64PROJ_LIB;
 65#else
 660;
 67#endif
 68
 69/************************************************************************/
 70/*                           pj_set_finder()                            */
 71/************************************************************************/
 72
 73void pj_set_finder( const char *(*new_finder)(const char *) )
 74
 75{
 76    pj_finder = new_finder;
 77}
 78
 79/************************************************************************/
 80/*                         pj_set_searchpath()                          */
 81/*                                                                      */
 82/*      Path control for callers that can't practically provide         */
 83/*      pj_set_finder() style callbacks.  Call with (0,NULL) as args    */
 84/*      to clear the searchpath set.                                    */
 85/************************************************************************/
 86
 87void pj_set_searchpath ( int count, const char **path )
 88{
 89    int i;
 90
 91    if (path_count > 0 && search_path != NULL)
 92    {
 93        for (i = 0; i < path_count; i++)
 94        {
 95            pj_dalloc(search_path[i]);
 96        }
 97        pj_dalloc(search_path);
 98        path_count = 0;
 99        search_path = NULL;
100    }
101
102    if( count > 0 )
103    {
104        search_path = pj_malloc(sizeof *search_path * count);
105        for (i = 0; i < count; i++)
106        {
107            search_path[i] = pj_malloc(strlen(path[i]) + 1);
108            strcpy(search_path[i], path[i]);
109        }
110    }
111        
112    path_count = count;
113}
114
115/************************************************************************/
116/*                            pj_open_lib()                             */
117/************************************************************************/
118
119FILE *
120pj_open_lib(char *name, char *mode) {
121    char fname[MAX_PATH_FILENAME+1];
122    const char *sysname;
123    FILE *fid;
124    int n = 0;
125    int i;
126#ifdef WIN32
127    static const char dir_chars[] = "/\\";
128#else
129    static const char dir_chars[] = "/";
130#endif
131
132#ifndef _WIN32_WCE
133
134    /* check if ~/name */
135    if (*name == '~' && strchr(dir_chars,name[1]) ) {
136        sysname = getenv("HOME");
137	   if (sysname) {
138            (void)strcpy(fname, sysname);
139            fname[n = strlen(fname)] = DIR_CHAR;
140            fname[++n] = '\0';
141            (void)strcpy(fname+n, name + 1);
142            sysname = fname;
143        } else
144            return NULL;
145
146    /* or fixed path: /name, ./name or ../name */
147    } else if (
148             strchr(dir_chars,*name)
149             || (*name == '.' && strchr(dir_chars,name[1])) 
150             || (!strncmp(name, "..", 2) && strchr(dir_chars,name[2]))
151             || (name[1] == ':' && strchr(dir_chars,name[2]))
152    ) {
153        sysname = name;
154
155    /* or try to use application provided file finder */
156    } else if( pj_finder != NULL && pj_finder( name ) != NULL ) {
157        sysname = pj_finder( name );
158
159    /* or is environment PROJ_LIB defined */
160    } else if ((sysname = getenv("PROJ_LIB")) || (sysname = proj_lib_name)) {
161        (void)strcpy(fname, sysname);
162        fname[n = strlen(fname)] = DIR_CHAR;
163        fname[++n] = '\0';
164        (void)strcpy(fname+n, name);
165        sysname = fname;
166    } else /* just try it bare bones */
167        sysname = name;
168
169    fid = fopen(sysname, mode);
170    if (fid)
171        errno = 0;
172
173    /* If none of those work and we have a search path, try it */
174    if (!fid && path_count > 0)
175    {
176        for (i = 0; fid == NULL && i < path_count; i++)
177        {
178            sprintf(fname, "%s%c%s", search_path[i], DIR_CHAR, name);
179            sysname = fname;
180            fid = fopen (sysname, mode);
181        }
182        if (fid)
183            errno = 0;
184    }
185
186    if( getenv( "PROJ_DEBUG" ) != NULL )
187        fprintf( stderr, "pj_open_lib(%s): call fopen(%s) - %s\n",
188                 name, sysname,
189                 fid == NULL ? "failed" : "succeeded" );
190
191    return(fid);
192#else
193    return NULL;
194#endif /* _WIN32_WCE */
195}