From 3175dce5fcec54fef6299cc8b595d84db5b29cf4 Mon Sep 17 00:00:00 2001 From: Aaron Puchert Date: Fri, 20 Oct 2017 12:58:10 +0200 Subject: Replace some asserts by compile-time assertions Decisions regarding the size of certain types are always made at compile time, hence this is where the assertion should take place. If the assertions fail, there is now a compiler error. --- src/PJ_cart.c | 1 - src/PJ_helmert.c | 1 - src/PJ_horner.c | 1 - src/PJ_pipeline.c | 1 - src/nad2bin.c | 12 ++++----- src/nad_init.c | 10 ------- src/pj_gridinfo.c | 78 +++++++++-------------------------------------------- src/pj_gridlist.c | 10 ------- src/proj_api.h | 2 +- src/proj_internal.h | 2 ++ src/projects.h | 11 +++++++- 11 files changed, 31 insertions(+), 98 deletions(-) (limited to 'src') diff --git a/src/PJ_cart.c b/src/PJ_cart.c index cd1995c1..12b5876a 100644 --- a/src/PJ_cart.c +++ b/src/PJ_cart.c @@ -43,7 +43,6 @@ #define PJ_LIB__ #include "proj_internal.h" #include "projects.h" -#include #include #include #include diff --git a/src/PJ_helmert.c b/src/PJ_helmert.c index d0fd8222..6c4b520c 100644 --- a/src/PJ_helmert.c +++ b/src/PJ_helmert.c @@ -43,7 +43,6 @@ Last update: 2017-05-15 ***********************************************************************/ #define PJ_LIB__ -#include #include #include #include "proj_internal.h" diff --git a/src/PJ_horner.c b/src/PJ_horner.c index 6f1450cd..fe0452d6 100644 --- a/src/PJ_horner.c +++ b/src/PJ_horner.c @@ -78,7 +78,6 @@ #define PJ_LIB__ #include "proj_internal.h" #include "projects.h" -#include #include #include #include diff --git a/src/PJ_pipeline.c b/src/PJ_pipeline.c index 35f79213..c8ce8582 100644 --- a/src/PJ_pipeline.c +++ b/src/PJ_pipeline.c @@ -102,7 +102,6 @@ Thomas Knudsen, thokn@sdfe.dk, 2016-05-20 #include "proj_internal.h" #include "projects.h" -#include #include #include PROJ_HEAD(pipeline, "Transformation pipeline manager"); diff --git a/src/nad2bin.c b/src/nad2bin.c index 0001189c..8401df79 100644 --- a/src/nad2bin.c +++ b/src/nad2bin.c @@ -1,10 +1,10 @@ /* Convert bivariate ASCII NAD27 to NAD83 tables to NTv2 binary structure */ #include #include -#include #define PJ_LIB__ -#include +#include "proj_internal.h" +#include "projects.h" #define U_SEC_TO_RAD 4.848136811095359935899141023e-12 /************************************************************************/ @@ -177,8 +177,8 @@ int main(int argc, char **argv) { exit(2); } - assert( MAX_TAB_ID == 80 ); - assert( sizeof(int) == 4 ); /* for ct.lim.lam/phi */ + STATIC_ASSERT( MAX_TAB_ID == 80 ); + STATIC_ASSERT( sizeof(pj_int32) == 4 ); /* for ct.lim.lam/phi */ memset( header, 0, sizeof(header) ); @@ -267,13 +267,13 @@ int main(int argc, char **argv) { { unsigned char achHeader[11*16]; double dfValue; - int nGSCount = ct.lim.lam * ct.lim.phi; + pj_int32 nGSCount = ct.lim.lam * ct.lim.phi; LP ur; ur.lam = ct.ll.lam + (ct.lim.lam-1) * ct.del.lam; ur.phi = ct.ll.phi + (ct.lim.phi-1) * ct.del.phi; - assert( sizeof(nGSCount) == 4 ); + STATIC_ASSERT( sizeof(nGSCount) == 4 ); memset( achHeader, 0, sizeof(achHeader) ); diff --git a/src/nad_init.c b/src/nad_init.c index a9082f8f..99342aa5 100644 --- a/src/nad_init.c +++ b/src/nad_init.c @@ -32,16 +32,6 @@ #include #include -#ifdef _WIN32_WCE -/* assert.h includes all Windows API headers and causes 'LP' name clash. - * Here assert we disable assert() for Windows CE. - * TODO - mloskot: re-implement porting friendly assert - */ -# define assert(exp) ((void)0) -#else -# include -#endif /* _WIN32_WCE */ - /************************************************************************/ /* swap_words() */ /* */ diff --git a/src/pj_gridinfo.c b/src/pj_gridinfo.c index ad4695ca..9b9a8d82 100644 --- a/src/pj_gridinfo.c +++ b/src/pj_gridinfo.c @@ -28,21 +28,12 @@ #define PJ_LIB__ -#include +#include "proj_internal.h" +#include "projects.h" #include #include #include -#ifdef _WIN32_WCE -/* assert.h includes all Windows API headers and causes 'LP' name clash. - * Here assert we disable assert() for Windows CE. - * TODO - mloskot: re-implement porting friendly assert - */ -# define assert(exp) ((void)0) -#else -# include -#endif /* _WIN32_WCE */ - /************************************************************************/ /* swap_words() */ /* */ @@ -431,23 +422,8 @@ static int pj_gridinfo_init_ntv2( projCtx ctx, PAFile fid, PJ_GRIDINFO *gilist ) int num_subfiles, subfile; int must_swap; - assert( sizeof(int) == 4 ); - assert( sizeof(double) == 8 ); -#ifdef _MSC_VER -#pragma warning( push ) -/* disable conditional expression is constant */ -#pragma warning( disable : 4127 ) -#endif - if( sizeof(int) != 4 || sizeof(double) != 8 ) -#ifdef _MSC_VER -#pragma warning( pop ) -#endif - { - pj_log( ctx, PJ_LOG_ERROR, - "basic types of inappropraiate size in pj_gridinfo_init_ntv2()" ); - pj_ctx_set_errno( ctx, -38 ); - return 0; - } + STATIC_ASSERT( sizeof(pj_int32) == 4 ); + STATIC_ASSERT( sizeof(double) == 8 ); /* -------------------------------------------------------------------- */ /* Read the overview header. */ @@ -541,8 +517,8 @@ static int pj_gridinfo_init_ntv2( projCtx ctx, PAFile fid, PJ_GRIDINFO *gilist ) ct->del.lam = *((double *) (header+9*16+8)); ct->del.phi = *((double *) (header+8*16+8)); - ct->lim.lam = (int) (fabs(ur.lam-ct->ll.lam)/ct->del.lam + 0.5) + 1; - ct->lim.phi = (int) (fabs(ur.phi-ct->ll.phi)/ct->del.phi + 0.5) + 1; + ct->lim.lam = (pj_int32) (fabs(ur.lam-ct->ll.lam)/ct->del.lam + 0.5) + 1; + ct->lim.phi = (pj_int32) (fabs(ur.phi-ct->ll.phi)/ct->del.phi + 0.5) + 1; pj_log( ctx, PJ_LOG_DEBUG_MINOR, "NTv2 %s %dx%d: LL=(%.9g,%.9g) UR=(%.9g,%.9g)\n", @@ -669,23 +645,8 @@ static int pj_gridinfo_init_ntv1( projCtx ctx, PAFile fid, PJ_GRIDINFO *gi ) struct CTABLE *ct; LP ur; - assert( sizeof(int) == 4 ); - assert( sizeof(double) == 8 ); -#ifdef _MSC_VER -#pragma warning( push ) -/* disable conditional expression is constant */ -#pragma warning( disable : 4127 ) -#endif - if( sizeof(int) != 4 || sizeof(double) != 8 ) -#ifdef _MSC_VER -#pragma warning( pop ) -#endif - { - pj_log( ctx, PJ_LOG_ERROR, - "basic types of inappropraiate size in nad_load_ntv1()" ); - pj_ctx_set_errno( ctx, -38 ); - return 0; - } + STATIC_ASSERT( sizeof(pj_int32) == 4 ); + STATIC_ASSERT( sizeof(double) == 8 ); /* -------------------------------------------------------------------- */ /* Read the header. */ @@ -734,8 +695,8 @@ static int pj_gridinfo_init_ntv1( projCtx ctx, PAFile fid, PJ_GRIDINFO *gi ) ur.phi = *((double *) (header+40)); ct->del.lam = *((double *) (header+104)); ct->del.phi = *((double *) (header+88)); - ct->lim.lam = (int) (fabs(ur.lam-ct->ll.lam)/ct->del.lam + 0.5) + 1; - ct->lim.phi = (int) (fabs(ur.phi-ct->ll.phi)/ct->del.phi + 0.5) + 1; + ct->lim.lam = (pj_int32) (fabs(ur.lam-ct->ll.lam)/ct->del.lam + 0.5) + 1; + ct->lim.phi = (pj_int32) (fabs(ur.phi-ct->ll.phi)/ct->del.phi + 0.5) + 1; pj_log( ctx, PJ_LOG_DEBUG_MINOR, "NTv1 %dx%d: LL=(%.9g,%.9g) UR=(%.9g,%.9g)", @@ -769,23 +730,8 @@ static int pj_gridinfo_init_gtx( projCtx ctx, PAFile fid, PJ_GRIDINFO *gi ) double xorigin,yorigin,xstep,ystep; int rows, columns; - assert( sizeof(int) == 4 ); - assert( sizeof(double) == 8 ); -#ifdef _MSC_VER -#pragma warning( push ) -/* disable conditional expression is constant */ -#pragma warning( disable : 4127 ) -#endif - if( sizeof(int) != 4 || sizeof(double) != 8 ) -#ifdef _MSC_VER -#pragma warning( pop ) -#endif - { - pj_log( ctx, PJ_LOG_ERROR, - "basic types of inappropraiate size in nad_load_gtx()" ); - pj_ctx_set_errno( ctx, -38 ); - return 0; - } + STATIC_ASSERT( sizeof(pj_int32) == 4 ); + STATIC_ASSERT( sizeof(double) == 8 ); /* -------------------------------------------------------------------- */ /* Read the header. */ diff --git a/src/pj_gridlist.c b/src/pj_gridlist.c index 4617591c..fbefdcea 100644 --- a/src/pj_gridlist.c +++ b/src/pj_gridlist.c @@ -33,16 +33,6 @@ #include #include -#ifdef _WIN32_WCE -/* assert.h includes all Windows API headers and causes 'LP' name clash. - * Here assert we disable assert() for Windows CE. - * TODO - mloskot: re-implement porting friendly assert - */ -# define assert(exp) ((void)0) -#else -# include -#endif /* _WIN32_WCE */ - static PJ_GRIDINFO *grid_list = NULL; #define PJ_MAX_PATH_LENGTH 1024 diff --git a/src/proj_api.h b/src/proj_api.h index b57d9f38..e5209615 100644 --- a/src/proj_api.h +++ b/src/proj_api.h @@ -69,10 +69,10 @@ extern "C" { -#ifndef PROJ_H extern char const pj_release[]; /* global release id string */ extern int pj_errno; /* global error return code */ +#ifndef PROJ_H /* In proj.h these macros are replaced by the enumeration pj_log_level */ #define PJ_LOG_NONE 0 #define PJ_LOG_ERROR 1 diff --git a/src/proj_internal.h b/src/proj_internal.h index fd6dc75d..4e70e690 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -48,6 +48,8 @@ extern "C" { #endif +#define STATIC_ASSERT(COND) ((void)sizeof(char[(COND) ? 1 : -1])) + #ifndef PJ_TODEG #define PJ_TODEG(rad) ((rad)*180.0/M_PI) #endif diff --git a/src/projects.h b/src/projects.h index 99df0e3e..8c0f81fa 100644 --- a/src/projects.h +++ b/src/projects.h @@ -43,6 +43,7 @@ #endif /* standard inclusions */ +#include #include #include #include @@ -78,6 +79,14 @@ extern "C" { # define ABS(x) ((x<0) ? (-1*(x)) : x) #endif +#if INT_MAX == 2147483647 +typedef int pj_int32; +#elif LONG_MAX == 2147483647 +typedef long pj_int32; +#else +#warning It seems no 32-bit integer type is available +#endif + /* maximum path/filename */ #ifndef MAX_PATH_FILENAME #define MAX_PATH_FILENAME 1024 @@ -618,7 +627,7 @@ PJ *pj_projection_specific_setup_##name (PJ *P) #define MAX_TAB_ID 80 typedef struct { float lam, phi; } FLP; -typedef struct { int lam, phi; } ILP; +typedef struct { pj_int32 lam, phi; } ILP; struct CTABLE { char id[MAX_TAB_ID]; /* ascii info */ -- cgit v1.2.3 From 8c6fe8b673c9876e7301d4a890403a931540c17c Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Tue, 28 Nov 2017 16:09:17 +1300 Subject: Add tests for GDA2020 (#688) Add GDA2020 tests, and correct the PJ_helmert bug they revealed --- src/PJ_helmert.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/PJ_helmert.c b/src/PJ_helmert.c index d0fd8222..79c7ad53 100644 --- a/src/PJ_helmert.c +++ b/src/PJ_helmert.c @@ -572,7 +572,8 @@ PJ *TRANSFORMATION(helmert, 0) { proj_log_debug(P, "ds=% 3.5f epoch=% 5.5f tobs=% 5.5f", Q->dscale, Q->epoch, Q->t_obs); } - if ((Q->opk.o==0) && (Q->opk.p==0) && (Q->opk.k==0) && (Q->scale==0)) { + if ((Q->opk.o==0) && (Q->opk.p==0) && (Q->opk.k==0) && (Q->scale==0) && + (Q->dopk.o==0) && (Q->dopk.p==0) && (Q->dopk.k==0)) { Q->no_rotation = 1; return P; } -- cgit v1.2.3 From 1c1d04b45d76366f54e104f9346879fd48bfde8e Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Tue, 28 Nov 2017 18:34:02 +1300 Subject: Enable selective debug printout through negative PROJ_DEBUG values (#689) * Enable selective debug printout through negative PROJ_DEBUG values --- src/pj_ctx.c | 2 +- src/pj_internal.c | 2 +- src/pj_log.c | 11 ++++++++++- src/proj_api.h | 5 +++-- 4 files changed, 15 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/pj_ctx.c b/src/pj_ctx.c index 326249ac..fc52f300 100644 --- a/src/pj_ctx.c +++ b/src/pj_ctx.c @@ -84,7 +84,7 @@ projCtx pj_get_default_ctx() if( getenv("PROJ_DEBUG") != NULL ) { - if( atoi(getenv("PROJ_DEBUG")) > 0 ) + if( atoi(getenv("PROJ_DEBUG")) >= -PJ_LOG_DEBUG_MINOR ) default_context.debug_level = atoi(getenv("PROJ_DEBUG")); else default_context.debug_level = PJ_LOG_DEBUG_MINOR; diff --git a/src/pj_internal.c b/src/pj_internal.c index efa9bd1f..8a5d2d15 100644 --- a/src/pj_internal.c +++ b/src/pj_internal.c @@ -183,7 +183,7 @@ enum proj_log_level proj_log_level (PJ_CONTEXT *ctx, enum proj_log_level log_lev ctx = pj_get_default_ctx(); if (0==ctx) return PJ_LOG_TELL; - previous = ctx->debug_level; + previous = abs (ctx->debug_level); if (PJ_LOG_TELL==log_level) return previous; ctx->debug_level = log_level; diff --git a/src/pj_log.c b/src/pj_log.c index 2525d050..bab5f078 100644 --- a/src/pj_log.c +++ b/src/pj_log.c @@ -51,8 +51,17 @@ void pj_vlog( projCtx ctx, int level, const char *fmt, va_list args ) { char *msg_buf; + int debug_level = ctx->debug_level; + int shutup_unless_errno_set = debug_level < 0; - if( level > ctx->debug_level ) + /* For negative debug levels, we first start logging when errno is set */ + if (ctx->last_errno==0 && shutup_unless_errno_set) + return; + + if (debug_level < 0) + debug_level = -debug_level; + + if( level > debug_level ) return; msg_buf = (char *) malloc(100000); diff --git a/src/proj_api.h b/src/proj_api.h index b57d9f38..50999b71 100644 --- a/src/proj_api.h +++ b/src/proj_api.h @@ -72,15 +72,16 @@ extern "C" { #ifndef PROJ_H extern char const pj_release[]; /* global release id string */ extern int pj_errno; /* global error return code */ +#endif -/* In proj.h these macros are replaced by the enumeration pj_log_level */ +#ifndef PROJ_INTERNAL_H +/* replaced by enum proj_log_level in proj_internal.h */ #define PJ_LOG_NONE 0 #define PJ_LOG_ERROR 1 #define PJ_LOG_DEBUG_MAJOR 2 #define PJ_LOG_DEBUG_MINOR 3 #endif - #ifdef PROJ_API_H_NOT_INVOKED_AS_PRIMARY_API /* These make the function declarations below conform with classic proj */ typedef PJ *projPJ; /* projPJ is a pointer to PJ */ -- cgit v1.2.3 From e51a6c255822d0a1b1320a2f519610f8802a5e27 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Tue, 28 Nov 2017 08:16:42 +0100 Subject: Free formatting of PROJ key=value pairs --- src/proj_4D_api.c | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c index 9a576997..5f4bf334 100644 --- a/src/proj_4D_api.c +++ b/src/proj_4D_api.c @@ -381,40 +381,60 @@ PJ *proj_create (PJ_CONTEXT *ctx, const char *definition) { Create a new PJ object in the context ctx, using the given definition. If ctx==0, the default context is used, if definition==0, or invalid, a null-pointer is returned. The definition may use '+' as argument start indicator, as in - "+proj=utm +zone=32", or leave it out, as in "proj=utm zone=32" + "+proj=utm +zone=32", or leave it out, as in "proj=utm zone=32". + + It may even use free formatting "proj = utm; zone =32 ellps= GRS80". + Note that the semicolon separator is allowed, but not required. **************************************************************************************/ PJ *P; char *args, **argv; - int argc, i, j, n; + int argc, i, j, last, n; if (0==ctx) ctx = pj_get_default_ctx (); - /* make a copy that we can manipulate */ + /* Make a copy that we can manipulate */ n = (int) strlen (definition); args = (char *) malloc (n + 1); if (0==args) return 0; strcpy (args, definition); - /* all-in-one: count args, eliminate superfluous whitespace, 0-terminate substrings */ - for (i = j = argc = 0; i < n; ) { - /* skip prefix whitespace */ + /* All-in-one: count args, eliminate superfluous whitespace, 0-terminate substrings */ + for (i = j = argc = last = 0; i < n; ) { + + /* Skip prefix whitespace */ while (isspace (args[i])) i++; - /* skip at most one prefix '+' */ + /* Skip at most one prefix '+' */ if ('+'==args[i]) i++; - /* whitespace after a '+' is a syntax error - but by Postel's prescription, we ignore and go on */ + /* Whitespace after a '+' is a syntax error - but by Postel's prescription, we ignore and go on */ if (isspace (args[i])) continue; - /* move a whitespace delimited text string to the left, skipping over superfluous whitespace */ - while ((0!=args[i]) && (!isspace (args[i]))) + /* Move a whitespace delimited text string to the left, skipping over superfluous whitespace */ + while ((0!=args[i]) && (!isspace (args[i])) && (';'!=args[i])) args[j++] = args[i++]; + /* Skip postfix whitespace */ + while (isspace (args[i]) || ';'==args[i]) + i++; + + /* Greedy assignment operator: turn "a = b" into "a=b" */ + if ('='==args[i]) { + args[j++] = '='; + i++; + while (isspace (args[i])) + i++; + while ((0!=args[i]) && (!isspace (args[i])) && (';'!=args[i])) + args[j++] = args[i++]; + while (isspace (args[i]) || ';'==args[i]) + i++; + } + /* terminate string - if that makes j pass i (often the case for first arg), let i catch up */ args[j++] = 0; if (i < j) @@ -422,10 +442,6 @@ PJ *proj_create (PJ_CONTEXT *ctx, const char *definition) { /* we finished another arg */ argc++; - - /* skip postfix whitespace */ - while (isspace (args[i])) - i++; } /* turn the massaged input into an array of strings */ -- cgit v1.2.3 From 38f717fb6b9838fd30ef1388bc66cd14005309bd Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Wed, 29 Nov 2017 20:25:40 +0100 Subject: Fix bad typedef that surfaces when including proj.h and proj_api.h in the same file (#687) Fix bad typedef that surfaces when including proj.h and proj_api.h in the same file --- src/proj_api.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/proj_api.h b/src/proj_api.h index f5ced282..597a2589 100644 --- a/src/proj_api.h +++ b/src/proj_api.h @@ -83,7 +83,7 @@ extern int pj_errno; /* global error return code */ #ifdef PROJ_API_H_NOT_INVOKED_AS_PRIMARY_API /* These make the function declarations below conform with classic proj */ typedef PJ *projPJ; /* projPJ is a pointer to PJ */ - typedef projCtx_t *projCtx; /* projCtx is a pointer to projCtx_t */ + typedef struct projCtx_t *projCtx; /* projCtx is a pointer to projCtx_t */ # define projXY XY # define projLP LP # define projXYZ XYZ -- cgit v1.2.3