/Proj4/pj_open_lib.c

http://github.com/route-me/route-me · C · 195 lines · 106 code · 22 blank · 67 comment · 39 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. #define PJ_LIB__
  51. #include "projects.h"
  52. #include <stdio.h>
  53. #include <string.h>
  54. #include <errno.h>
  55. PJ_CVSID("$Id: pj_open_lib.c,v 1.9 2007/07/06 14:58:03 fwarmerdam Exp $");
  56. static const char *(*pj_finder)(const char *) = NULL;
  57. static int path_count = 0;
  58. static char **search_path = NULL;
  59. static char * proj_lib_name =
  60. #ifdef PROJ_LIB
  61. PROJ_LIB;
  62. #else
  63. 0;
  64. #endif
  65. /************************************************************************/
  66. /* pj_set_finder() */
  67. /************************************************************************/
  68. void pj_set_finder( const char *(*new_finder)(const char *) )
  69. {
  70. pj_finder = new_finder;
  71. }
  72. /************************************************************************/
  73. /* pj_set_searchpath() */
  74. /* */
  75. /* Path control for callers that can't practically provide */
  76. /* pj_set_finder() style callbacks. Call with (0,NULL) as args */
  77. /* to clear the searchpath set. */
  78. /************************************************************************/
  79. void pj_set_searchpath ( int count, const char **path )
  80. {
  81. int i;
  82. if (path_count > 0 && search_path != NULL)
  83. {
  84. for (i = 0; i < path_count; i++)
  85. {
  86. pj_dalloc(search_path[i]);
  87. }
  88. pj_dalloc(search_path);
  89. path_count = 0;
  90. search_path = NULL;
  91. }
  92. if( count > 0 )
  93. {
  94. search_path = pj_malloc(sizeof *search_path * count);
  95. for (i = 0; i < count; i++)
  96. {
  97. search_path[i] = pj_malloc(strlen(path[i]) + 1);
  98. strcpy(search_path[i], path[i]);
  99. }
  100. }
  101. path_count = count;
  102. }
  103. /************************************************************************/
  104. /* pj_open_lib() */
  105. /************************************************************************/
  106. FILE *
  107. pj_open_lib(char *name, char *mode) {
  108. char fname[MAX_PATH_FILENAME+1];
  109. const char *sysname;
  110. FILE *fid;
  111. int n = 0;
  112. int i;
  113. #ifdef WIN32
  114. static const char dir_chars[] = "/\\";
  115. #else
  116. static const char dir_chars[] = "/";
  117. #endif
  118. #ifndef _WIN32_WCE
  119. /* check if ~/name */
  120. if (*name == '~' && strchr(dir_chars,name[1]) ) {
  121. sysname = getenv("HOME");
  122. if (sysname) {
  123. (void)strcpy(fname, sysname);
  124. fname[n = strlen(fname)] = DIR_CHAR;
  125. fname[++n] = '\0';
  126. (void)strcpy(fname+n, name + 1);
  127. sysname = fname;
  128. } else
  129. return NULL;
  130. /* or fixed path: /name, ./name or ../name */
  131. } else if (
  132. strchr(dir_chars,*name)
  133. || (*name == '.' && strchr(dir_chars,name[1]))
  134. || (!strncmp(name, "..", 2) && strchr(dir_chars,name[2]))
  135. || (name[1] == ':' && strchr(dir_chars,name[2]))
  136. ) {
  137. sysname = name;
  138. /* or try to use application provided file finder */
  139. } else if( pj_finder != NULL && pj_finder( name ) != NULL ) {
  140. sysname = pj_finder( name );
  141. /* or is environment PROJ_LIB defined */
  142. } else if ((sysname = getenv("PROJ_LIB")) || (sysname = proj_lib_name)) {
  143. (void)strcpy(fname, sysname);
  144. fname[n = strlen(fname)] = DIR_CHAR;
  145. fname[++n] = '\0';
  146. (void)strcpy(fname+n, name);
  147. sysname = fname;
  148. } else /* just try it bare bones */
  149. sysname = name;
  150. fid = fopen(sysname, mode);
  151. if (fid)
  152. errno = 0;
  153. /* If none of those work and we have a search path, try it */
  154. if (!fid && path_count > 0)
  155. {
  156. for (i = 0; fid == NULL && i < path_count; i++)
  157. {
  158. sprintf(fname, "%s%c%s", search_path[i], DIR_CHAR, name);
  159. sysname = fname;
  160. fid = fopen (sysname, mode);
  161. }
  162. if (fid)
  163. errno = 0;
  164. }
  165. if( getenv( "PROJ_DEBUG" ) != NULL )
  166. fprintf( stderr, "pj_open_lib(%s): call fopen(%s) - %s\n",
  167. name, sysname,
  168. fid == NULL ? "failed" : "succeeded" );
  169. return(fid);
  170. #else
  171. return NULL;
  172. #endif /* _WIN32_WCE */
  173. }