aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gie.c6
-rw-r--r--src/pj_internal.c54
-rw-r--r--src/pj_malloc.c1
-rw-r--r--src/proj.h16
-rw-r--r--src/proj_4D_api.c238
-rw-r--r--src/proj_internal.h2
-rw-r--r--src/projects.h1
7 files changed, 160 insertions, 158 deletions
diff --git a/src/gie.c b/src/gie.c
index 40820e59..9931b2ef 100644
--- a/src/gie.c
+++ b/src/gie.c
@@ -1492,7 +1492,7 @@ static int pj_cart_selftest (void) {
size_t n, sz;
double dist, h, t;
char *args[3] = {"proj=utm", "zone=32", "ellps=GRS80"};
- const char *arg = {"+proj=utm +zone=32 +ellps=GRS80"};
+ char arg[50] = {"+proj=utm; +zone=32; +ellps=GRS80"};
char buf[40];
/* An utm projection on the GRS80 ellipsoid */
@@ -1723,7 +1723,8 @@ static int pj_cart_selftest (void) {
if (strcmp(info.version, tmpstr)) return 55;
}
if (info.release[0] == '\0') return 56;
- if (info.searchpath[0] == '\0') return 57;
+ if (getenv ("HOME") || getenv ("PROJ_LIB"))
+ if (info.searchpath[0] == '\0') return 57;
/* proj_pj_info() */
P = proj_create(PJ_DEFAULT_CTX, "+proj=august"); /* august has no inverse */
@@ -1733,6 +1734,7 @@ static int pj_cart_selftest (void) {
P = proj_create(PJ_DEFAULT_CTX, arg);
pj_info = proj_pj_info(P);
if ( !pj_info.has_inverse ) { proj_destroy(P); return 61; }
+ pj_shrink (arg);
if ( strcmp(pj_info.definition, arg) ) { proj_destroy(P); return 62; }
if ( strcmp(pj_info.id, "utm") ) { proj_destroy(P); return 63; }
diff --git a/src/pj_internal.c b/src/pj_internal.c
index 6bb33d64..4dbcfbd4 100644
--- a/src/pj_internal.c
+++ b/src/pj_internal.c
@@ -148,56 +148,6 @@ void proj_context_inherit (PJ *parent, PJ *child) {
-/**************************************************************************************/
-size_t pj_strlcpy(char *dst, const char *src, size_t dsize) {
-/***************************************************************************************
- Copy src to string dst of size siz. At most siz-1 characters
- will be copied. Always NUL terminates (unless siz == 0).
- Returns strlen(src); if retval >= siz, truncation occurred.
-
- *
- * Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
-
- Source: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/string/strlcpy.c
-
-***************************************************************************************/
- const char *osrc = src;
- size_t nleft = dsize;
-
- /* Copy as many bytes as will fit. */
- if (nleft != 0) {
- while (--nleft != 0) {
- if ((*dst++ = *src++) == '\0')
- break;
- }
- }
-
- /* Not enough room in dst, add NUL and traverse rest of src. */
- if (nleft == 0) {
- if (dsize != 0)
- *dst = '\0'; /* NUL-terminate dst */
- while (*src++)
- ;
- }
-
- return(src - osrc - 1); /* count does not include NUL */
-}
-
-
-
/*****************************************************************************/
char *pj_chomp (char *c) {
/******************************************************************************
@@ -261,7 +211,9 @@ consuming their surrounding whitespace.
/* Eliminate prefix '+', only if preceeded by whitespace */
/* (i.e. keep it in 1.23e+08) */
- if ((i > 0) && ('+'==c[j]) && isspace (c[i]))
+ if ((i > 0) && ('+'==c[j]) && ws)
+ c[j] = ' ';
+ if ((i==0) && ('+'==c[j]))
c[j] = ' ';
if (isspace (c[j]) || ';'==c[j]) {
diff --git a/src/pj_malloc.c b/src/pj_malloc.c
index 73a60599..127e76ee 100644
--- a/src/pj_malloc.c
+++ b/src/pj_malloc.c
@@ -221,6 +221,7 @@ void *pj_default_destructor (PJ *P, int errlev) { /* Destructor */
/* free parameter list elements */
pj_dealloc_params (pj_get_ctx(P), P->params, errlev);
+ pj_dealloc (P->def_full);
/* free the cs2cs emulation elements */
pj_free (P->axisswap);
diff --git a/src/proj.h b/src/proj.h
index c3165cfe..73629490 100644
--- a/src/proj.h
+++ b/src/proj.h
@@ -239,20 +239,22 @@ union PJ_COORD {
struct PJ_INFO {
- char release[64]; /* Release info. Version + date */
- char version[64]; /* Full version number */
int major; /* Major release number */
int minor; /* Minor release number */
int patch; /* Patch level */
- char searchpath[512]; /* Paths where init and grid files are */
+ const char *release; /* Release info. Version + date */
+ const char *version; /* Full version number */
+ const char *searchpath; /* Paths where init and grid files are */
/* looked for. Paths are separated by */
/* semi-colons. */
+ const char * const *paths;
+ size_t path_count;
};
struct PJ_PROJ_INFO {
- char id[16]; /* Name of the projection in question */
- char description[128]; /* Description of the projection */
- char definition[512]; /* Projection definition */
+ const char *id; /* Name of the projection in question */
+ const char *description; /* Description of the projection */
+ const char *definition; /* Projection definition */
int has_inverse; /* 1 if an inverse mapping exists, 0 otherwise */
double accuracy; /* Expected accuracy of the transformation. -1 if unknown. */
};
@@ -356,7 +358,7 @@ int proj_errno_restore (const PJ *P, int err);
PJ_FACTORS proj_factors(PJ *P, LP lp);
/* Info functions - get information about various PROJ.4 entities */
-PJ_INFO proj_info(void);
+PJ_INFO proj_info(void);
PJ_PROJ_INFO proj_pj_info(PJ *P);
PJ_GRID_INFO proj_grid_info(const char *gridname);
PJ_INIT_INFO proj_init_info(const char *initname);
diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c
index 0d50407f..42e3cbf9 100644
--- a/src/proj_4D_api.c
+++ b/src/proj_4D_api.c
@@ -724,70 +724,113 @@ PJ_CONTEXT *proj_context_destroy (PJ_CONTEXT *ctx) {
}
+
+
+
+
/*****************************************************************************/
-PJ_INFO proj_info(void) {
+static char *path_append (char *buf, const char *app, size_t *buf_size) {
/******************************************************************************
- Basic info about the current instance of the PROJ.4 library.
+ Helper for proj_info() below. Append app to buf, separated by a
+ semicolon. Also handle allocation of longer buffer if needed.
+
+ Returns buffer and adjusts *buf_size through provided pointer arg.
+******************************************************************************/
+ char *p;
+ size_t len, applen = 0, buflen = 0;
+#ifdef _WIN32
+ char *delim = ";";
+#else
+ char *delim = ":";
+#endif
+
+ /* Nothing to do? */
+ if (0 == app)
+ return buf;
+ applen = strlen (app);
+ if (0 == applen)
+ return buf;
+
+ /* Start checking whether buf is long enough */
+ if (0 != buf)
+ buflen = strlen (buf);
+ len = buflen+applen+strlen (delim) + 1;
+
+ /* "pj_realloc", so to speak */
+ if (*buf_size < len) {
+ p = pj_calloc (2 * len, sizeof (char));
+ if (0==p) {
+ pj_dealloc (buf);
+ return 0;
+ }
+ *buf_size = 2 * len;
+ if (buf != 0)
+ strcpy (p, buf);
+ pj_dealloc (buf);
+ buf = p;
+ }
+
+ /* Only append a semicolon if something's already there */
+ if (0 != buflen)
+ strcat (buf, ";");
+ strcat (buf, app);
+ return buf;
+}
- Returns PJ_INFO struct. Searchpath member of the struct is truncated to 512
- characters.
+static const char *empty = {""};
+static char version[64] = {""};
+static PJ_INFO info = {0, 0, 0, 0, 0, 0, 0, 0};
+static volatile int info_initialized = 0;
+/*****************************************************************************/
+PJ_INFO proj_info (void) {
+/******************************************************************************
+ Basic info about the current instance of the PROJ.4 library.
+
+ Returns PJ_INFO struct.
******************************************************************************/
- PJ_INFO info;
const char * const *paths;
- char *tmpstr;
- int i, n;
- size_t len = 0;
+ size_t i, n;
+
+ size_t buf_size = 0;
+ char *buf = 0;
- memset(&info, 0, sizeof(PJ_INFO));
+ pj_acquire_lock ();
+
+ if (0!=info_initialized) {
+ pj_release_lock ();
+ return info;
+ }
info.major = PROJ_VERSION_MAJOR;
info.minor = PROJ_VERSION_MINOR;
info.patch = PROJ_VERSION_PATCH;
/* This is a controlled environment, so no risk of sprintf buffer
- overflow. A normal version string is xx.yy.zz which is 8 characters
- long and there is room for 64 bytes in the version string. */
- sprintf(info.version, "%d.%d.%d", info.major, info.minor, info.patch);
-
- pj_strlcpy(info.release, pj_get_release(), sizeof(info.release));
+ overflow. A normal version string is xx.yy.zz which is 8 characters
+ long and there is room for 64 bytes in the version string. */
+ sprintf (version, "%d.%d.%d", info.major, info.minor, info.patch);
+ info.searchpath = empty;
+ info.version = version;
+ info.release = pj_get_release ();
/* build search path string */
- tmpstr = getenv("HOME");
- if (tmpstr != NULL) {
- pj_strlcpy(info.searchpath, tmpstr, sizeof(info.searchpath));
- }
+ buf = path_append (buf, getenv ("HOME"), &buf_size);
+ buf = path_append (buf, getenv ("PROJ_LIB"), &buf_size);
- tmpstr = getenv("PROJ_LIB");
- if (tmpstr != NULL) {
- if (strlen(info.searchpath) != 0) {
- /* $HOME already in path */
- strcat(info.searchpath, ";");
- len = strlen(tmpstr);
- strncat(info.searchpath, tmpstr, sizeof(info.searchpath)-len-1);
- } else {
- /* path is empty */
- pj_strlcpy(info.searchpath, tmpstr, sizeof(info.searchpath));
- }
- }
-
- paths = proj_get_searchpath();
- n = proj_get_path_count();
+ paths = proj_get_searchpath ();
+ n = (size_t) proj_get_path_count ();
- for (i=0; i<n; i++) {
- if (strlen(info.searchpath)+strlen(paths[i]) >= 511)
- continue;
+ for (i = 0; i < n; i++)
+ buf = path_append (buf, paths[i], &buf_size);
+ info.searchpath = buf ? buf : empty;
- if (strlen(info.searchpath) != 0) {
- strcat(info.searchpath, ";");
- len = strlen(paths[i]);
- strncat(info.searchpath, paths[i], sizeof(info.searchpath)-len-1);
- } else {
- pj_strlcpy(info.searchpath, paths[i], sizeof(info.searchpath));
- }
- }
+ info.paths = paths;
+ info.path_count = n;
+ info_initialized = 1;
+ pj_release_lock ();
return info;
}
@@ -798,37 +841,41 @@ PJ_PROJ_INFO proj_pj_info(PJ *P) {
Basic info about a particular instance of a projection object.
Returns PJ_PROJ_INFO struct.
-
******************************************************************************/
- PJ_PROJ_INFO info;
+ PJ_PROJ_INFO pjinfo;
char *def;
- memset(&info, 0, sizeof(PJ_PROJ_INFO));
+ memset(&pjinfo, 0, sizeof(PJ_PROJ_INFO));
/* Expected accuracy of the transformation. Hardcoded for now, will be improved */
/* later. Most likely to be used when a transformation is set up with */
/* proj_create_crs_to_crs in a future version that leverages the EPSG database. */
- info.accuracy = -1.0;
+ pjinfo.accuracy = -1.0;
- if (!P) {
- return info;
- }
+ if (0==P)
+ return pjinfo;
/* projection id */
if (pj_param(P->ctx, P->params, "tproj").i)
- pj_strlcpy(info.id, pj_param(P->ctx, P->params, "sproj").s, sizeof(info.id));
+ pjinfo.id = pj_param(P->ctx, P->params, "sproj").s;
/* projection description */
- pj_strlcpy(info.description, P->descr, sizeof(info.description));
+ pjinfo.description = P->descr;
/* projection definition */
- def = pj_get_def(P, 0); /* pj_get_def takes a non-const PJ pointer */
- pj_strlcpy(info.definition, &def[1], sizeof(info.definition)); /* def includes a leading space */
- pj_dealloc(def);
-
- info.has_inverse = pj_has_inverse(P);
+ if (P->def_full)
+ def = P->def_full;
+ else
+ def = pj_get_def(P, 0); /* pj_get_def takes a non-const PJ pointer */
+ if (0==def)
+ pjinfo.definition = empty;
+ else
+ pjinfo.definition = pj_shrink (def);
+ /* Make pj_free clean this up eventually */
+ P->def_full = def;
- return info;
+ pjinfo.has_inverse = pj_has_inverse(P);
+ return pjinfo;
}
@@ -838,47 +885,49 @@ PJ_GRID_INFO proj_grid_info(const char *gridname) {
Information about a named datum grid.
Returns PJ_GRID_INFO struct.
-
******************************************************************************/
- PJ_GRID_INFO info;
+ PJ_GRID_INFO grinfo;
/*PJ_CONTEXT *ctx = proj_context_create(); */
PJ_CONTEXT *ctx = pj_get_default_ctx();
PJ_GRIDINFO *gridinfo = pj_gridinfo_init(ctx, gridname);
- memset(&info, 0, sizeof(PJ_GRID_INFO));
+ memset(&grinfo, 0, sizeof(PJ_GRID_INFO));
/* in case the grid wasn't found */
if (gridinfo->filename == NULL) {
pj_gridinfo_free(ctx, gridinfo);
- strcpy(info.format, "missing");
- return info;
+ strcpy(grinfo.format, "missing");
+ return grinfo;
}
+ /* The string copies below are automatically null-terminated due to */
+ /* the memset above, so strncpy is safe */
+
/* name of grid */
- pj_strlcpy(info.gridname, gridname, sizeof(info.gridname));
+ strncpy (grinfo.gridname, gridname, sizeof(grinfo.gridname) - 1);
/* full path of grid */
- pj_find_file(ctx, gridname, info.filename, sizeof(info.filename));
+ pj_find_file(ctx, gridname, grinfo.filename, sizeof(grinfo.filename) - 1);
/* grid format */
- pj_strlcpy(info.format, gridinfo->format, sizeof(info.format));
+ strncpy (grinfo.format, gridinfo->format, sizeof(grinfo.format) - 1);
/* grid size */
- info.n_lon = gridinfo->ct->lim.lam;
- info.n_lat = gridinfo->ct->lim.phi;
+ grinfo.n_lon = gridinfo->ct->lim.lam;
+ grinfo.n_lat = gridinfo->ct->lim.phi;
/* cell size */
- info.cs_lon = gridinfo->ct->del.lam;
- info.cs_lat = gridinfo->ct->del.phi;
+ grinfo.cs_lon = gridinfo->ct->del.lam;
+ grinfo.cs_lat = gridinfo->ct->del.phi;
/* bounds of grid */
- info.lowerleft = gridinfo->ct->ll;
- info.upperright.lam = info.lowerleft.lam + info.n_lon*info.cs_lon;
- info.upperright.phi = info.lowerleft.phi + info.n_lat*info.cs_lat;
+ grinfo.lowerleft = gridinfo->ct->ll;
+ grinfo.upperright.lam = grinfo.lowerleft.lam + grinfo.n_lon*grinfo.cs_lon;
+ grinfo.upperright.phi = grinfo.lowerleft.phi + grinfo.n_lat*grinfo.cs_lat;
pj_gridinfo_free(ctx, gridinfo);
- return info;
+ return grinfo;
}
@@ -897,27 +946,28 @@ PJ_INIT_INFO proj_init_info(const char *initname){
If the init file is found, but the metadata is missing, the value is
set to "Unknown".
-
******************************************************************************/
int file_found;
char param[80], key[74];
paralist *start, *next;
- PJ_INIT_INFO info;
+ PJ_INIT_INFO ininfo;
PJ_CONTEXT *ctx = pj_get_default_ctx();
- memset(&info, 0, sizeof(PJ_INIT_INFO));
+ memset(&ininfo, 0, sizeof(PJ_INIT_INFO));
- file_found = pj_find_file(ctx, initname, info.filename, sizeof(info.filename));
+ file_found = pj_find_file(ctx, initname, ininfo.filename, sizeof(ininfo.filename));
if (!file_found || strlen(initname) > 64) {
- return info;
+ return ininfo;
}
- pj_strlcpy(info.name, initname, sizeof(info.name));
- strcpy(info.origin, "Unknown");
- strcpy(info.version, "Unknown");
- strcpy(info.lastupdate, "Unknown");
+ /* The initial memset (0) makes strncpy safe here */
+ strncpy (ininfo.name, initname, sizeof(ininfo.name) - 1);
+ strcpy(ininfo.origin, "Unknown");
+ strcpy(ininfo.version, "Unknown");
+ strcpy(ininfo.lastupdate, "Unknown");
- pj_strlcpy(key, initname, 64); /* make room for ":metadata\0" at the end */
+ strncpy (key, initname, 64); /* make room for ":metadata\0" at the end */
+ key[64] = 0;
strncat(key, ":metadata", 9);
strcpy(param, "+init=");
strncat(param, key, 73);
@@ -925,24 +975,21 @@ PJ_INIT_INFO proj_init_info(const char *initname){
start = pj_mkparam(param);
pj_expand_init(ctx, start);
- if (pj_param(ctx, start, "tversion").i) {
- pj_strlcpy(info.version, pj_param(ctx, start, "sversion").s, sizeof(info.version));
- }
+ if (pj_param(ctx, start, "tversion").i)
+ strncpy(ininfo.version, pj_param(ctx, start, "sversion").s, sizeof(ininfo.version) - 1);
- if (pj_param(ctx, start, "torigin").i) {
- pj_strlcpy(info.origin, pj_param(ctx, start, "sorigin").s, sizeof(info.origin));
- }
+ if (pj_param(ctx, start, "torigin").i)
+ strncpy(ininfo.origin, pj_param(ctx, start, "sorigin").s, sizeof(ininfo.origin) - 1);
- if (pj_param(ctx, start, "tlastupdate").i) {
- pj_strlcpy(info.lastupdate, pj_param(ctx, start, "slastupdate").s, sizeof(info.lastupdate));
- }
+ if (pj_param(ctx, start, "tlastupdate").i)
+ strncpy(ininfo.lastupdate, pj_param(ctx, start, "slastupdate").s, sizeof(ininfo.lastupdate) - 1);
for ( ; start; start = next) {
next = start->next;
pj_dalloc(start);
}
- return info;
+ return ininfo;
}
@@ -957,7 +1004,6 @@ PJ_FACTORS proj_factors(PJ *P, LP lp) {
returns PJ_FACTORS. If unsuccessfull, error number is set and the
struct returned contains NULL data.
-
******************************************************************************/
PJ_FACTORS factors = {0,0,0, 0,0,0, 0,0, 0,0,0,0};
struct FACTORS f;
diff --git a/src/proj_internal.h b/src/proj_internal.h
index 3e0ecbe9..bc3b2dd1 100644
--- a/src/proj_internal.h
+++ b/src/proj_internal.h
@@ -132,8 +132,6 @@ void proj_fileapi_set (PJ *P, void *fileapi);
const char * const *proj_get_searchpath(void);
int proj_get_path_count(void);
-size_t pj_strlcpy(char *dst, const char *src, size_t siz);
-
#ifdef __cplusplus
}
#endif
diff --git a/src/projects.h b/src/projects.h
index 41f4aa3c..60bac8a1 100644
--- a/src/projects.h
+++ b/src/projects.h
@@ -231,6 +231,7 @@ struct PJconsts {
projCtx_t *ctx;
const char *descr; /* From pj_list.h or individual PJ_*.c file */
paralist *params; /* Parameter list */
+ char *def_full; /* Full textual definition (usually 0 - set by proj_pj_info) */
char *def_size; /* Shape and size parameters extracted from params */
char *def_shape;
char *def_spherification;