From 244a24104ded3a4573aeffa32160af21f76cbce6 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 15 Dec 2020 00:51:46 +0100 Subject: Revise error codes to have a reduced set exposed in the public API. Fixes #2482 And also add proj_context_errno_string() Revise gie 'expect failure errno XXXX' strings --- src/4D_api.cpp | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) (limited to 'src/4D_api.cpp') diff --git a/src/4D_api.cpp b/src/4D_api.cpp index d6eb901d..612be716 100644 --- a/src/4D_api.cpp +++ b/src/4D_api.cpp @@ -176,7 +176,8 @@ double proj_roundtrip (PJ *P, PJ_DIRECTION direction, int n, PJ_COORD *coord) { return HUGE_VAL; if (n < 1) { - proj_errno_set (P, EINVAL); + proj_log_error(P, _("n should be >= 1")); + proj_errno_set (P, PROJ_ERR_OTHER_API_MISUSE); return HUGE_VAL; } @@ -294,7 +295,7 @@ similarly, but prefers the 2D resp. 3D interfaces if available. if( iRetry > 0 ) { const int oldErrno = proj_errno_reset(P); if (proj_log_level(P->ctx, PJ_LOG_TELL) >= PJ_LOG_DEBUG) { - pj_log(P->ctx, PJ_LOG_DEBUG, proj_errno_string(oldErrno)); + pj_log(P->ctx, PJ_LOG_DEBUG, proj_context_errno_string(P->ctx, oldErrno)); } pj_log(P->ctx, PJ_LOG_DEBUG, "Did not result in valid result. " @@ -312,7 +313,7 @@ similarly, but prefers the 2D resp. 3D interfaces if available. } PJ_COORD res = direction == PJ_FWD ? pj_fwd4d( coord, alt.pj ) : pj_inv4d( coord, alt.pj ); - if( proj_errno(alt.pj) == PJD_ERR_NETWORK_ERROR ) { + if( proj_errno(alt.pj) == PROJ_ERR_OTHER_NETWORK_ERROR ) { return proj_coord_error (); } if( res.xyzt.x != HUGE_VAL ) { @@ -359,21 +360,14 @@ similarly, but prefers the 2D resp. 3D interfaces if available. } } - proj_errno_set (P, EINVAL); + proj_errno_set (P, PROJ_ERR_COORD_TRANSFM_NO_OPERATION); return proj_coord_error (); } - switch (direction) { - case PJ_FWD: - return pj_fwd4d (coord, P); - case PJ_INV: - return pj_inv4d (coord, P); - default: - break; - } - - proj_errno_set (P, EINVAL); - return proj_coord_error (); + if (direction == PJ_FWD) + return pj_fwd4d (coord, P); + else + return pj_inv4d (coord, P); } @@ -500,9 +494,6 @@ size_t proj_trans_generic ( break; case PJ_IDENT: return nmin; - default: - proj_errno_set (P, EINVAL); - return 0; } /* Arrays of length==0 are broadcast as the constant 0 */ @@ -771,7 +762,7 @@ PJ *pj_create_internal (PJ_CONTEXT *ctx, const char *definition) { n = strlen (definition); args = (char *) malloc (n + 1); if (nullptr==args) { - proj_context_errno_set(ctx, ENOMEM); + proj_context_errno_set(ctx, PROJ_ERR_INVALID_OP /*ENOMEM*/); return nullptr; } strcpy (args, definition); @@ -779,14 +770,14 @@ PJ *pj_create_internal (PJ_CONTEXT *ctx, const char *definition) { argc = pj_trim_argc (args); if (argc==0) { free (args); - proj_context_errno_set(ctx, PJD_ERR_NO_ARGS); + proj_context_errno_set(ctx, PROJ_ERR_INVALID_OP_MISSING_ARG); return nullptr; } argv = pj_trim_argv (argc, args); if (!argv) { free(args); - proj_context_errno_set(ctx, ENOMEM); + proj_context_errno_set(ctx, PROJ_ERR_INVALID_OP /*ENOMEM*/); return nullptr; } @@ -821,14 +812,14 @@ indicator, as in {"+proj=utm", "+zone=32"}, or leave it out, as in {"proj=utm", if (nullptr==ctx) ctx = pj_get_default_ctx (); if (nullptr==argv) { - proj_context_errno_set(ctx, PJD_ERR_NO_ARGS); + proj_context_errno_set(ctx, PROJ_ERR_INVALID_OP_MISSING_ARG); return nullptr; } /* We assume that free format is used, and build a full proj_create compatible string */ c = pj_make_args (argc, argv); if (nullptr==c) { - proj_context_errno_set(ctx, ENOMEM); + proj_context_errno_set(ctx, PROJ_ERR_INVALID_OP /* ENOMEM */); return nullptr; } @@ -849,14 +840,14 @@ Same as proj_create_argv() but calls pj_create_internal() instead of proj_create if (nullptr==ctx) ctx = pj_get_default_ctx (); if (nullptr==argv) { - proj_context_errno_set(ctx, PJD_ERR_NO_ARGS); + proj_context_errno_set(ctx, PROJ_ERR_INVALID_OP_MISSING_ARG); return nullptr; } /* We assume that free format is used, and build a full proj_create compatible string */ c = pj_make_args (argc, argv); if (nullptr==c) { - proj_context_errno_set(ctx, ENOMEM); + proj_context_errno_set(ctx, PROJ_ERR_INVALID_OP /*ENOMEM*/); return nullptr; } -- cgit v1.2.3 From 1d803550e7059729cf2734fc6190993e8b8404bf Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 15 Dec 2020 01:12:58 +0100 Subject: proj_trans_array(): make it transform all coordinates even when an error occurs --- src/4D_api.cpp | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) (limited to 'src/4D_api.cpp') diff --git a/src/4D_api.cpp b/src/4D_api.cpp index 612be716..556a8c2d 100644 --- a/src/4D_api.cpp +++ b/src/4D_api.cpp @@ -377,18 +377,43 @@ int proj_trans_array (PJ *P, PJ_DIRECTION direction, size_t n, PJ_COORD *coord) /****************************************************************************** Batch transform an array of PJ_COORD. + Performs transformation on all points, even if errors occur on some points. + + Individual points that fail to transform will have their components set to + HUGE_VAL + Returns 0 if all coordinates are transformed without error, otherwise - returns error number. + returns a precise error number if all coordinates that fail to transform + for the same reason, or a generic error code if they fail for different + reasons. ******************************************************************************/ size_t i; + int retErrno = 0; + bool hasSetRetErrno = false; + bool sameRetErrno = true; for (i = 0; i < n; i++) { + proj_context_errno_set(P->ctx, 0); coord[i] = proj_trans (P, direction, coord[i]); - if (proj_errno(P)) - return proj_errno (P); - } + int thisErrno = proj_errno(P); + if( thisErrno != 0 ) + { + if( !hasSetRetErrno ) + { + retErrno = thisErrno; + hasSetRetErrno = true; + } + else if( sameRetErrno && retErrno != thisErrno ) + { + sameRetErrno = false; + retErrno = PROJ_ERR_COORD_TRANSFM; + } + } + } + + proj_context_errno_set(P->ctx, retErrno); - return 0; + return retErrno; } -- cgit v1.2.3 From a27c0255e7b8e6aab1b91e49fd7870d1ee4e1a80 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 15 Dec 2020 17:53:29 +0100 Subject: Remap ENOMEM from PROJ_ERR_INVALID_OP to PROJ_ERR_OTHER --- src/4D_api.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/4D_api.cpp') diff --git a/src/4D_api.cpp b/src/4D_api.cpp index 556a8c2d..7423240f 100644 --- a/src/4D_api.cpp +++ b/src/4D_api.cpp @@ -787,7 +787,7 @@ PJ *pj_create_internal (PJ_CONTEXT *ctx, const char *definition) { n = strlen (definition); args = (char *) malloc (n + 1); if (nullptr==args) { - proj_context_errno_set(ctx, PROJ_ERR_INVALID_OP /*ENOMEM*/); + proj_context_errno_set(ctx, PROJ_ERR_OTHER /*ENOMEM*/); return nullptr; } strcpy (args, definition); @@ -802,7 +802,7 @@ PJ *pj_create_internal (PJ_CONTEXT *ctx, const char *definition) { argv = pj_trim_argv (argc, args); if (!argv) { free(args); - proj_context_errno_set(ctx, PROJ_ERR_INVALID_OP /*ENOMEM*/); + proj_context_errno_set(ctx, PROJ_ERR_OTHER /*ENOMEM*/); return nullptr; } @@ -872,7 +872,7 @@ Same as proj_create_argv() but calls pj_create_internal() instead of proj_create /* We assume that free format is used, and build a full proj_create compatible string */ c = pj_make_args (argc, argv); if (nullptr==c) { - proj_context_errno_set(ctx, PROJ_ERR_INVALID_OP /*ENOMEM*/); + proj_context_errno_set(ctx, PROJ_ERR_OTHER /*ENOMEM*/); return nullptr; } -- cgit v1.2.3