diff options
| author | Thomas Knudsen <thokn@sdfe.dk> | 2017-09-27 13:56:34 +0200 |
|---|---|---|
| committer | Thomas Knudsen <thokn@sdfe.dk> | 2017-10-06 11:39:27 +0200 |
| commit | 664577ced6a8e4074b1f53af82b5ae5d1d189eac (patch) | |
| tree | a29d4a6c0842bb87df63fc913502c3b6c5b097a5 | |
| parent | 0495fdca92fc620d44572ce1e4e871f57f968198 (diff) | |
| download | PROJ-664577ced6a8e4074b1f53af82b5ae5d1d189eac.tar.gz PROJ-664577ced6a8e4074b1f53af82b5ae5d1d189eac.zip | |
Enable default destructor for all PJ objects.
In most cases memory deallocation is completely removed from the
code since it can be handled by the default destructor. In a few
special cases a local destructor overrides the default destructor
and makes sure that locally allocated memored is cleaned up correctly.
Move all deallocation from pj_free to pj_default_destructor
Rename pj_latlong.c to fit with the conventional format PJ_latlong.c - freeup was missed here due to wrong naming
Clean up pj_init to avoid double deallocation; Also resolve #576 by adding z_0 and t_0 options in pj_init, while cleaning
Add a prototype for dealloc_params
Added missing errno.h include in pj_ctx.c
Temporarily removing ob_tran from testvarious, to be sure that is where the trouble is
Make PJ_ob_tran.c use proper initialization for the chained projection
proj=ob_tran: make it clear, that we disallow ellipsoidal projections, and, for improved backwards compatibility, turns off default settings, which could inject unwanted ellipsoid definitions
... then also remove the ellipsoid definition from the testvarious test case - which is probably buggy anyway
Work around cs2cs spherical init bug in testvarious; Forbid defs for ob_tran in pj_init
128 files changed, 907 insertions, 2428 deletions
diff --git a/nad/testvarious b/nad/testvarious index f11bc806..4ca20a63 100755 --- a/nad/testvarious +++ b/nad/testvarious @@ -642,14 +642,14 @@ EOF echo "##############################################################" >> ${OUT} echo "Check inverse error handling with ob_tran (#225)" >> ${OUT} $EXE +proj=ob_tran \ - +o_proj=moll +o_lon_p=LON_POLE +o_lat_p=LAT_POLE +lon_0=180 +ellps=WGS84 \ + +o_proj=moll +a=6378137 +es=0 +o_lon_p=LON_POLE +o_lat_p=LAT_POLE +lon_0=180 \ -E >>${OUT} <<EOF 300000 400000 20000000 30000000 EOF echo "Test inverse handling" >> ${OUT} $EXE -I +proj=ob_tran \ - +o_proj=moll +o_lon_p=LON_POLE +o_lat_p=LAT_POLE +lon_0=180 +ellps=WGS84 \ + +o_proj=moll +a=6378137 +es=0 +o_lon_p=LON_POLE +o_lat_p=LAT_POLE +lon_0=180 \ -E >>${OUT} <<EOF 10 20 EOF @@ -894,6 +894,11 @@ if [ $? -ne 0 ] ; then echo "PROBLEMS HAVE OCCURRED" echo "test file ${OUT} saved" echo + echo "----------------------------------------------------------" + echo "${OUT}" + echo "----------------------------------------------------------" + cat ${OUT} + echo "----------------------------------------------------------" exit 100 else echo "TEST OK" diff --git a/src/Makefile.am b/src/Makefile.am index 12d11c5f..c9ebedd8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -49,7 +49,7 @@ libproj_la_SOURCES = \ PJ_tcc.c PJ_tcea.c PJ_times.c PJ_tmerc.c \ PJ_airy.c PJ_aitoff.c PJ_august.c PJ_bacon.c \ PJ_chamb.c PJ_hammer.c PJ_lagrng.c PJ_larr.c \ - PJ_lask.c PJ_nocol.c PJ_ob_tran.c PJ_oea.c \ + PJ_lask.c PJ_latlong.c PJ_nocol.c PJ_ob_tran.c PJ_oea.c \ PJ_tpeqd.c PJ_vandg.c PJ_vandg2.c PJ_vandg4.c \ PJ_wag7.c PJ_lcca.c PJ_geos.c proj_etmerc.c \ PJ_boggs.c PJ_collg.c PJ_comill.c PJ_crast.c PJ_denoy.c \ @@ -60,7 +60,7 @@ libproj_la_SOURCES = \ PJ_nell.c PJ_nell_h.c PJ_patterson.c PJ_putp2.c PJ_putp3.c \ PJ_putp4p.c PJ_putp5.c PJ_putp6.c PJ_qsc.c PJ_robin.c \ PJ_sch.c PJ_sts.c PJ_urm5.c PJ_urmfps.c PJ_wag2.c \ - PJ_wag3.c PJ_wink1.c PJ_wink2.c pj_latlong.c pj_geocent.c \ + PJ_wag3.c PJ_wink1.c PJ_wink2.c pj_geocent.c \ aasincos.c adjlon.c bch2bps.c bchgen.c \ biveval.c dmstor.c mk_cheby.c pj_auth.c \ pj_deriv.c pj_ell_set.c pj_ellps.c pj_errno.c \ diff --git a/src/PJ_aea.c b/src/PJ_aea.c index 7d0e935d..228d3afd 100644 --- a/src/PJ_aea.c +++ b/src/PJ_aea.c @@ -29,6 +29,7 @@ #define PJ_LIB__ #include <proj.h> +#include <errno.h> #include "projects.h" # define EPS10 1.e-10 @@ -79,23 +80,19 @@ struct pj_opaque { }; -static void *freeup_new (PJ *P) { /* Destructor */ +static void *destructor (PJ *P, int errlev) { /* Destructor */ if (0==P) return 0; if (0==P->opaque) - return pj_dealloc (P); + return pj_default_destructor (P, errlev); pj_dealloc (P->opaque->en); - pj_dealloc (P->opaque); - return pj_dealloc(P); + return pj_default_destructor (P, errlev); } -static void freeup (PJ *P) { - freeup_new (P); - return; -} + static XY e_forward (LP lp, PJ *P) { /* Ellipsoid/spheroid, forward */ @@ -154,17 +151,16 @@ static PJ *setup(PJ *P) { P->inv = e_inverse; P->fwd = e_forward; - if (fabs(Q->phi1 + Q->phi2) < EPS10) { - proj_errno_set(P, PJD_ERR_CONIC_LAT_EQUAL); - return freeup_new(P); - } + if (fabs(Q->phi1 + Q->phi2) < EPS10) + return destructor(P, PJD_ERR_CONIC_LAT_EQUAL); Q->n = sinphi = sin(Q->phi1); cosphi = cos(Q->phi1); secant = fabs(Q->phi1 - Q->phi2) >= EPS10; if( (Q->ellips = (P->es > 0.))) { double ml1, m1; - if (!(Q->en = pj_enfn(P->es))) return freeup_new(P); + if (!(Q->en = pj_enfn(P->es))) + return destructor(P, 0); m1 = pj_msfn(sinphi, cosphi, P->es); ml1 = pj_qsfn(sinphi, P->e, P->one_es); if (secant) { /* secant cone */ @@ -175,9 +171,8 @@ static PJ *setup(PJ *P) { m2 = pj_msfn(sinphi, cosphi, P->es); ml2 = pj_qsfn(sinphi, P->e, P->one_es); if (ml2 == ml1) - { - return freeup_new(P); - } + return destructor(P, 0); + Q->n = (m1 * m1 - m2 * m2) / (ml2 - ml1); } Q->ec = 1. - .5 * P->one_es * log((1. - P->e) / @@ -201,8 +196,9 @@ static PJ *setup(PJ *P) { PJ *PROJECTION(aea) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; + P->destructor = destructor; Q->phi1 = pj_param(P->ctx, P->params, "rlat_1").f; Q->phi2 = pj_param(P->ctx, P->params, "rlat_2").f; @@ -213,7 +209,7 @@ PJ *PROJECTION(aea) { PJ *PROJECTION(leac) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->phi2 = pj_param(P->ctx, P->params, "rlat_1").f; diff --git a/src/PJ_aeqd.c b/src/PJ_aeqd.c index 4a46cf1c..c6fa9e06 100644 --- a/src/PJ_aeqd.c +++ b/src/PJ_aeqd.c @@ -28,6 +28,7 @@ #define PJ_LIB__ #include "geodesic.h" #include <proj.h> +#include <errno.h> #include "projects.h" struct pj_opaque { @@ -54,23 +55,18 @@ PROJ_HEAD(aeqd, "Azimuthal Equidistant") "\n\tAzi, Sph&Ell\n\tlat_0 guam"; #define OBLIQ 3 -static void *freeup_new (PJ *P) { /* Destructor */ +static void *destructor (PJ *P, int errlev) { /* Destructor */ if (0==P) return 0; + if (0==P->opaque) - return pj_dealloc (P); + return pj_default_destructor (P, errlev); - if (P->opaque->en) - pj_dealloc(P->opaque->en); - pj_dealloc (P->opaque); - return pj_dealloc(P); + pj_dealloc (P->opaque->en); + return pj_default_destructor (P, errlev); } -static void freeup (PJ *P) { - freeup_new (P); - return; -} static XY e_guam_fwd(LP lp, PJ *P) { /* Guam elliptical */ XY xy = {0.0,0.0}; @@ -268,8 +264,9 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(aeqd) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; + P->destructor = destructor; geod_init(&Q->g, P->a, P->es / (1 + sqrt(P->one_es))); P->phi0 = pj_param(P->ctx, P->params, "rlat_0").f; @@ -290,7 +287,8 @@ PJ *PROJECTION(aeqd) { P->inv = s_inverse; P->fwd = s_forward; } else { - if (!(Q->en = pj_enfn(P->es))) return freeup_new(P); + if (!(Q->en = pj_enfn(P->es))) + return pj_default_destructor (P, 0); if (pj_param(P->ctx, P->params, "bguam").i) { Q->M1 = pj_mlfn(P->phi0, Q->sinph0, Q->cosph0, Q->en); P->inv = e_guam_inv; diff --git a/src/PJ_airy.c b/src/PJ_airy.c index 2c58bb79..d832b9b7 100644 --- a/src/PJ_airy.c +++ b/src/PJ_airy.c @@ -28,6 +28,7 @@ #define PJ_LIB__ #include <proj.h> +#include <errno.h> #include "projects.h" PROJ_HEAD(airy, "Airy") "\n\tMisc Sph, no inv.\n\tno_cut lat_b="; @@ -104,28 +105,13 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - PJ *PROJECTION(airy) { double beta; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/PJ_aitoff.c b/src/PJ_aitoff.c index 8b1d7f94..3455fa71 100644 --- a/src/PJ_aitoff.c +++ b/src/PJ_aitoff.c @@ -30,6 +30,7 @@ #define PJ_LIB__ #include <proj.h> +#include <errno.h> #include "projects.h" @@ -152,22 +153,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } - -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - static PJ *setup(PJ *P) { P->inv = s_inverse; P->fwd = s_forward; @@ -179,7 +164,7 @@ static PJ *setup(PJ *P) { PJ *PROJECTION(aitoff) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; Q->mode = 0; @@ -190,15 +175,13 @@ PJ *PROJECTION(aitoff) { PJ *PROJECTION(wintri) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; Q->mode = 1; if (pj_param(P->ctx, P->params, "tlat_1").i) { - if ((Q->cosphi1 = cos(pj_param(P->ctx, P->params, "rlat_1").f)) == 0.) { - proj_errno_set(P, PJD_ERR_LAT_LARGER_THAN_90); - return freeup_new(P); - } + if ((Q->cosphi1 = cos(pj_param(P->ctx, P->params, "rlat_1").f)) == 0.) + return pj_default_destructor (P, PJD_ERR_LAT_LARGER_THAN_90); } else /* 50d28' or acos(2/pi) */ Q->cosphi1 = 0.636619772367581343; diff --git a/src/PJ_august.c b/src/PJ_august.c index f5028938..d81644bf 100644 --- a/src/PJ_august.c +++ b/src/PJ_august.c @@ -23,15 +23,6 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ -static void *freeup_new (PJ *P) { /* Destructor */ - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - PJ *PROJECTION(august) { P->inv = 0; diff --git a/src/PJ_bacon.c b/src/PJ_bacon.c index a9c6da44..cb7286be 100644 --- a/src/PJ_bacon.c +++ b/src/PJ_bacon.c @@ -1,6 +1,7 @@ # define HLFPI2 2.46740110027233965467 /* (pi/2)^2 */ # define EPS 1e-10 #define PJ_LIB__ +#include <errno.h> #include <projects.h> @@ -34,26 +35,11 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - PJ *PROJECTION(bacon) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->bacn = 1; @@ -67,7 +53,7 @@ PJ *PROJECTION(bacon) { PJ *PROJECTION(apian) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->bacn = Q->ortl = 0; @@ -80,7 +66,7 @@ PJ *PROJECTION(apian) { PJ *PROJECTION(ortel) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->bacn = 0; diff --git a/src/PJ_bipc.c b/src/PJ_bipc.c index 97284fcc..0019d614 100644 --- a/src/PJ_bipc.c +++ b/src/PJ_bipc.c @@ -1,5 +1,6 @@ #define PJ_LIB__ #include <proj.h> +#include <errno.h> #include "projects.h" PROJ_HEAD(bipc, "Bipolar conic of western hemisphere") "\n\tConic Sph."; @@ -156,23 +157,10 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(bipc) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->noskew = pj_param(P->ctx, P->params, "bns").i; diff --git a/src/PJ_boggs.c b/src/PJ_boggs.c index 8ede9f16..e6efd7d3 100644 --- a/src/PJ_boggs.c +++ b/src/PJ_boggs.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +# include <errno.h> # include <projects.h> PROJ_HEAD(boggs, "Boggs Eumorphic") "\n\tPCyl., no inv., Sph."; # define NITER 20 @@ -33,15 +34,6 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ } -static void *freeup_new (PJ *P) { /* Destructor */ - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - PJ *PROJECTION(boggs) { P->es = 0.; diff --git a/src/PJ_bonne.c b/src/PJ_bonne.c index 2a576c60..368829c5 100644 --- a/src/PJ_bonne.c +++ b/src/PJ_bonne.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -83,20 +84,16 @@ static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ + +static void *destructor (PJ *P, int errlev) { /* Destructor */ if (0==P) return 0; + if (0==P->opaque) - return pj_dealloc (P); + return pj_default_destructor (P, errlev); pj_dealloc (P->opaque->en); - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; + return pj_default_destructor (P, errlev); } @@ -104,14 +101,14 @@ PJ *PROJECTION(bonne) { double c; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; + P->destructor = destructor; Q->phi1 = pj_param(P->ctx, P->params, "rlat_1").f; - if (fabs(Q->phi1) < EPS10) { - proj_errno_set(P, PJD_ERR_LAT1_IS_ZERO); - return freeup_new(P); - } + if (fabs(Q->phi1) < EPS10) + return destructor (P, PJD_ERR_LAT1_IS_ZERO); + if (P->es != 0.0) { Q->en = pj_enfn(P->es); Q->m1 = pj_mlfn(Q->phi1, Q->am1 = sin(Q->phi1), diff --git a/src/PJ_calcofi.c b/src/PJ_calcofi.c index 25521eed..b188f7e9 100644 --- a/src/PJ_calcofi.c +++ b/src/PJ_calcofi.c @@ -149,16 +149,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - return pj_dealloc (P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(calcofi) { P->opaque = 0; diff --git a/src/PJ_cart.c b/src/PJ_cart.c index d50036b5..eb2a66bc 100644 --- a/src/PJ_cart.c +++ b/src/PJ_cart.c @@ -108,11 +108,6 @@ PROJ_HEAD(cart, "Geodetic/cartesian conversions"); **************************************************************/ -static void freeup (PJ *P) { - pj_freeup_plain (P); - return; -} - /*********************************************************************/ static double normal_radius_of_curvature (double a, double es, double phi) { /*********************************************************************/ @@ -518,7 +513,8 @@ int pj_cart_selftest (void) { if ( strlen(init_info.filename) != 0 ) return 67; init_info = proj_init_info("epsg"); - if ( strcmp(init_info.origin, "EPSG") ) return 69; + /* Need to allow for "Unknown" until all commonly distributed EPSG-files comes with a metadata section */ + if ( strcmp(init_info.origin, "EPSG") && strcmp(init_info.origin, "Unknown") ) return 69; if ( strcmp(init_info.name, "epsg") ) return 68; diff --git a/src/PJ_cass.c b/src/PJ_cass.c index 85280205..6955146e 100644 --- a/src/PJ_cass.c +++ b/src/PJ_cass.c @@ -1,5 +1,6 @@ #define PJ_LIB__ -# include <projects.h> +# include <errno.h> +# include "projects.h" PROJ_HEAD(cass, "Cassini") "\n\tCyl, Sph&Ell"; @@ -77,22 +78,18 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ return lp; } - -static void *freeup_new(PJ *P) { /* Destructor */ +static void *destructor (PJ *P, int errlev) { /* Destructor */ if (0==P) return 0; + if (0==P->opaque) - return pj_dealloc (P); + return pj_default_destructor (P, errlev); - pj_dealloc(P->opaque->en); - pj_dealloc(P->opaque); - return pj_dealloc(P); + pj_dealloc (P->opaque->en); + return pj_default_destructor (P, errlev); } -static void freeup(PJ *P) { /* Destructor */ - freeup_new (P); - return; -} + PJ *PROJECTION(cass) { @@ -106,11 +103,12 @@ PJ *PROJECTION(cass) { /* otherwise it's ellipsoidal */ P->opaque = pj_calloc (1, sizeof (struct pj_opaque)); if (0==P->opaque) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); + P->destructor = destructor; P->opaque->en = pj_enfn (P->es); if (0==P->opaque->en) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque->m0 = pj_mlfn (P->phi0, sin (P->phi0), cos (P->phi0), P->opaque->en); P->inv = e_inverse; diff --git a/src/PJ_cc.c b/src/PJ_cc.c index d43f5a88..9ba51386 100644 --- a/src/PJ_cc.c +++ b/src/PJ_cc.c @@ -27,16 +27,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - PJ *PROJECTION(cc) { P->es = 0.; diff --git a/src/PJ_cea.c b/src/PJ_cea.c index 20f03547..0ec7376c 100644 --- a/src/PJ_cea.c +++ b/src/PJ_cea.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -52,46 +53,39 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ return (lp); } - -static void *freeup_new (PJ *P) { /* Destructor */ +static void *destructor (PJ *P, int errlev) { /* Destructor */ if (0==P) return 0; + if (0==P->opaque) - return pj_dealloc (P); + return pj_default_destructor (P, errlev); pj_dealloc (P->opaque->apa); - pj_dealloc (P->opaque); - return pj_dealloc (P); + return pj_default_destructor (P, errlev); } -static void freeup (PJ *P) { - freeup_new (P); - return; -} PJ *PROJECTION(cea) { double t = 0.0; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; + P->destructor = destructor; if (pj_param(P->ctx, P->params, "tlat_ts").i) { P->k0 = cos(t = pj_param(P->ctx, P->params, "rlat_ts").f); - if (P->k0 < 0.) { - proj_errno_set(P, PJD_ERR_LAT_TS_LARGER_THAN_90); - freeup_new(P); - return 0; - } + if (P->k0 < 0.) + return pj_default_destructor (P, PJD_ERR_LAT_TS_LARGER_THAN_90); } if (P->es != 0.0) { t = sin(t); P->k0 /= sqrt(1. - P->es * t * t); P->e = sqrt(P->es); - if (!(Q->apa = pj_authset(P->es))) { - return freeup_new(P); - } + if (!(Q->apa = pj_authset(P->es))) + return pj_default_destructor(P, ENOMEM); + Q->qp = pj_qsfn(1., P->e, P->one_es); P->inv = e_inverse; P->fwd = e_forward; diff --git a/src/PJ_chamb.c b/src/PJ_chamb.c index c6028a7a..9edb699f 100644 --- a/src/PJ_chamb.c +++ b/src/PJ_chamb.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -93,28 +94,13 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - PJ *PROJECTION(chamb) { int i, j; char line[10]; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -131,10 +117,8 @@ PJ *PROJECTION(chamb) { j = i == 2 ? 0 : i + 1; Q->c[i].v = vect(P->ctx,Q->c[j].phi - Q->c[i].phi, Q->c[i].cosphi, Q->c[i].sinphi, Q->c[j].cosphi, Q->c[j].sinphi, Q->c[j].lam - Q->c[i].lam); - if (Q->c[i].v.r == 0.0) { - proj_errno_set(P, PJD_ERR_CONTROL_POINT_NO_DIST); - return freeup_new(P); - } + if (Q->c[i].v.r == 0.0) + return pj_default_destructor (P, PJD_ERR_CONTROL_POINT_NO_DIST); /* co-linearity problem ignored for now */ } Q->beta_0 = lc(P->ctx,Q->c[0].v.r, Q->c[2].v.r, Q->c[1].v.r); diff --git a/src/PJ_collg.c b/src/PJ_collg.c index c646d99a..01c65cd0 100644 --- a/src/PJ_collg.c +++ b/src/PJ_collg.c @@ -41,16 +41,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(collg) { P->es = 0.0; P->inv = s_inverse; diff --git a/src/PJ_comill.c b/src/PJ_comill.c index 1a4508b1..a329c0ac 100644 --- a/src/PJ_comill.c +++ b/src/PJ_comill.c @@ -70,15 +70,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ return lp; } -static void *freeup_new (PJ *P) { /* Destructor */ - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - PJ *PROJECTION(comill) { P->es = 0; diff --git a/src/PJ_crast.c b/src/PJ_crast.c index 09c4f1e4..b47b0e55 100644 --- a/src/PJ_crast.c +++ b/src/PJ_crast.c @@ -29,17 +29,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(crast) { P->es = 0.0; P->inv = s_inverse; diff --git a/src/PJ_denoy.c b/src/PJ_denoy.c index 9eb818b9..3964c7da 100644 --- a/src/PJ_denoy.c +++ b/src/PJ_denoy.c @@ -22,16 +22,6 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ } -static void *freeup_new (PJ *P) { /* Destructor */ - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(denoy) { P->es = 0.0; P->fwd = s_forward; diff --git a/src/PJ_eck1.c b/src/PJ_eck1.c index da159017..bd5c1916 100644 --- a/src/PJ_eck1.c +++ b/src/PJ_eck1.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -#include <projects.h> +#include "projects.h" PROJ_HEAD(eck1, "Eckert I") "\n\tPCyl., Sph."; #define FC 0.92131773192356127802 @@ -28,23 +28,14 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - PJ *PROJECTION(eck1) { P->es = 0.0; P->inv = s_inverse; P->fwd = s_forward; - return P
; + return P +; } diff --git a/src/PJ_eck2.c b/src/PJ_eck2.c index 6ef2a96c..3b2e4e49 100644 --- a/src/PJ_eck2.c +++ b/src/PJ_eck2.c @@ -43,16 +43,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - return pj_dealloc (P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - PJ *PROJECTION(eck2) { P->es = 0.; diff --git a/src/PJ_eck3.c b/src/PJ_eck3.c index 3fe5c49f..8dc72c7c 100644 --- a/src/PJ_eck3.c +++ b/src/PJ_eck3.c @@ -1,5 +1,6 @@ #define PJ_LIB__ -#include <projects.h> +#include <errno.h> +#include "projects.h" PROJ_HEAD(eck3, "Eckert III") "\n\tPCyl, Sph."; PROJ_HEAD(putp1, "Putnins P1") "\n\tPCyl, Sph."; @@ -36,22 +37,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - static PJ *setup(PJ *P) { P->es = 0.; P->inv = s_inverse; @@ -63,7 +48,7 @@ static PJ *setup(PJ *P) { PJ *PROJECTION(eck3) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->C_x = 0.42223820031577120149; @@ -78,7 +63,7 @@ PJ *PROJECTION(eck3) { PJ *PROJECTION(kav7) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; /* Defined twice in original code - Using 0.866..., @@ -96,7 +81,7 @@ PJ *PROJECTION(kav7) { PJ *PROJECTION(wag6) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->C_x = Q->C_y = 0.94745; @@ -110,7 +95,7 @@ PJ *PROJECTION(wag6) { PJ *PROJECTION(putp1) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->C_x = 1.89490; diff --git a/src/PJ_eck4.c b/src/PJ_eck4.c index 358c0224..0ad9ec43 100644 --- a/src/PJ_eck4.c +++ b/src/PJ_eck4.c @@ -51,18 +51,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(eck4) { P->es = 0.0; P->inv = s_inverse; diff --git a/src/PJ_eck5.c b/src/PJ_eck5.c index 5fbdf7db..13617c1d 100644 --- a/src/PJ_eck5.c +++ b/src/PJ_eck5.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -#include <projects.h> +#include "projects.h" PROJ_HEAD(eck5, "Eckert V") "\n\tPCyl, Sph."; @@ -28,18 +28,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(eck5) { P->es = 0.0; P->inv = s_inverse; diff --git a/src/PJ_eqc.c b/src/PJ_eqc.c index 576e0e3a..4f471df1 100644 --- a/src/PJ_eqc.c +++ b/src/PJ_eqc.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -32,33 +33,14 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(eqc) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; - if ((Q->rc = cos(pj_param(P->ctx, P->params, "rlat_ts").f)) <= 0.) { - proj_errno_set(P, PJD_ERR_LAT_TS_LARGER_THAN_90); - return freeup_new(P); - } + if ((Q->rc = cos(pj_param(P->ctx, P->params, "rlat_ts").f)) <= 0.) + return pj_default_destructor (P, PJD_ERR_LAT_TS_LARGER_THAN_90); P->inv = s_inverse; P->fwd = s_forward; P->es = 0.; diff --git a/src/PJ_eqdc.c b/src/PJ_eqdc.c index eaf4db0b..6b3449f7 100644 --- a/src/PJ_eqdc.c +++ b/src/PJ_eqdc.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -66,23 +67,15 @@ static void special(LP lp, PJ *P, struct FACTORS *fac) { } -static void *freeup_new (PJ *P) { /* Destructor */ +static void *destructor (PJ *P, int errlev) { /* Destructor */ if (0==P) return 0; - if (0==P->opaque) - return pj_dealloc (P); - - if (P->opaque->en) - pj_dealloc (P->opaque->en); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} + if (0==P->opaque) + return pj_default_destructor (P, errlev); -static void freeup (PJ *P) { - freeup_new (P); - return; + pj_dealloc (P->opaque->en); + return pj_default_destructor (P, errlev); } @@ -92,20 +85,18 @@ PJ *PROJECTION(eqdc) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; + P->destructor = destructor; Q->phi1 = pj_param(P->ctx, P->params, "rlat_1").f; Q->phi2 = pj_param(P->ctx, P->params, "rlat_2").f; - if (fabs(Q->phi1 + Q->phi2) < EPS10) { - proj_errno_set(P, PJD_ERR_CONIC_LAT_EQUAL); - freeup_new(P); - return 0; - } + if (fabs(Q->phi1 + Q->phi2) < EPS10) + pj_default_destructor (P, PJD_ERR_CONIC_LAT_EQUAL); if (!(Q->en = pj_enfn(P->es))) - return freeup_new(P); + return pj_default_destructor(P, ENOMEM); Q->n = sinphi = sin(Q->phi1); cosphi = cos(Q->phi1); diff --git a/src/PJ_fahey.c b/src/PJ_fahey.c index 4f4b92a4..42318f8f 100644 --- a/src/PJ_fahey.c +++ b/src/PJ_fahey.c @@ -29,19 +29,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(fahey) { P->es = 0.; P->inv = s_inverse; diff --git a/src/PJ_fouc_s.c b/src/PJ_fouc_s.c index 32eeeb4f..343e5878 100644 --- a/src/PJ_fouc_s.c +++ b/src/PJ_fouc_s.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -48,34 +49,16 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(fouc_s) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->n = pj_param(P->ctx, P->params, "dn").f; - if (Q->n < 0. || Q->n > 1.) { - proj_errno_set(P, PJD_ERR_N_OUT_OF_RANGE); - return freeup_new(P); - } + if (Q->n < 0. || Q->n > 1.) + return pj_default_destructor (P, PJD_ERR_N_OUT_OF_RANGE); + Q->n1 = 1. - Q->n; P->es = 0; P->inv = s_inverse; diff --git a/src/PJ_gall.c b/src/PJ_gall.c index bca36bc7..01a56e33 100644 --- a/src/PJ_gall.c +++ b/src/PJ_gall.c @@ -31,20 +31,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(gall) { P->es = 0.0; diff --git a/src/PJ_geos.c b/src/PJ_geos.c index b929c06b..5679455f 100644 --- a/src/PJ_geos.c +++ b/src/PJ_geos.c @@ -28,6 +28,7 @@ */ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -189,46 +190,25 @@ static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(geos) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; - if ((Q->h = pj_param(P->ctx, P->params, "dh").f) <= 0.){ - proj_errno_set(P, PJD_ERR_H_LESS_THAN_ZERO); - return freeup_new(P); - } + if ((Q->h = pj_param(P->ctx, P->params, "dh").f) <= 0.) + pj_default_destructor (P, PJD_ERR_H_LESS_THAN_ZERO); - if (P->phi0 != 0.0) { - proj_errno_set(P, PJD_ERR_UNKNOWN_PRIME_MERIDIAN); - return freeup_new(P); - } + if (P->phi0 != 0.0) + pj_default_destructor (P, PJD_ERR_UNKNOWN_PRIME_MERIDIAN); Q->sweep_axis = pj_param(P->ctx, P->params, "ssweep").s; if (Q->sweep_axis == NULL) Q->flip_axis = 0; else { - if (Q->sweep_axis[1] != '\0' || (Q->sweep_axis[0] != 'x' && Q->sweep_axis[0] != 'y')) { - proj_errno_set(P, PJD_ERR_INVALID_SWEEP_AXIS); - return freeup_new(P); - } + if (Q->sweep_axis[1] != '\0' || (Q->sweep_axis[0] != 'x' && Q->sweep_axis[0] != 'y')) + pj_default_destructor (P, PJD_ERR_INVALID_SWEEP_AXIS); + if (Q->sweep_axis[0] == 'x') Q->flip_axis = 1; else diff --git a/src/PJ_gins8.c b/src/PJ_gins8.c index 48bdf3a5..b27ec092 100644 --- a/src/PJ_gins8.c +++ b/src/PJ_gins8.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -#include <projects.h> +#include "projects.h" PROJ_HEAD(gins8, "Ginsburg VIII (TsNIIGAiK)") "\n\tPCyl, Sph., no inv."; @@ -22,19 +22,6 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(gins8) { P->es = 0.0; P->inv = 0; diff --git a/src/PJ_gn_sinu.c b/src/PJ_gn_sinu.c index 57bbecc8..745cd5ca 100644 --- a/src/PJ_gn_sinu.c +++ b/src/PJ_gn_sinu.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -86,40 +87,18 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_msg (PJ *P, int errlev) { /* Destructor */ +static void *destructor (PJ *P, int errlev) { /* Destructor */ if (0==P) return 0; - if (0!=P->ctx) - pj_ctx_set_errno (P->ctx, errlev); - - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; if (0==P->opaque) - return pj_dealloc (P); - - if (P->opaque->en) - pj_dalloc(P->opaque->en); + return pj_default_destructor (P, errlev); - pj_dealloc (P->opaque); - return pj_dealloc(P); + pj_dealloc (P->opaque->en); + return pj_default_destructor (P, errlev); } -static void freeup (PJ *P) { - freeup_new (P); - return; -} - /* for spheres, only */ static void setup(PJ *P) { @@ -135,12 +114,13 @@ static void setup(PJ *P) { PJ *PROJECTION(sinu) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; + P->destructor = destructor; if (!(Q->en = pj_enfn(P->es))) - return freeup_new(P); - + return pj_default_destructor (P, ENOMEM); + if (P->es != 0.0) { P->inv = e_inverse; P->fwd = e_forward; @@ -156,8 +136,9 @@ PJ *PROJECTION(sinu) { PJ *PROJECTION(eck6) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; + P->destructor = destructor; Q->m = 1.; Q->n = 2.570796326794896619231321691; @@ -170,8 +151,9 @@ PJ *PROJECTION(eck6) { PJ *PROJECTION(mbtfps) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; + P->destructor = destructor; Q->m = 0.5; Q->n = 1.785398163397448309615660845; @@ -184,16 +166,17 @@ PJ *PROJECTION(mbtfps) { PJ *PROJECTION(gn_sinu) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; + P->destructor = destructor; if (pj_param(P->ctx, P->params, "tn").i && pj_param(P->ctx, P->params, "tm").i) { Q->n = pj_param(P->ctx, P->params, "dn").f; Q->m = pj_param(P->ctx, P->params, "dm").f; if (Q->n < 0 || Q->m < 0) - return freeup_msg(P, PJD_ERR_INVALID_M_OR_N); + return destructor (P, PJD_ERR_INVALID_M_OR_N); } else - return freeup_msg(P, PJD_ERR_INVALID_M_OR_N); + return destructor (P, PJD_ERR_INVALID_M_OR_N); setup(P); diff --git a/src/PJ_gnom.c b/src/PJ_gnom.c index 099f32fb..1d3f3386 100644 --- a/src/PJ_gnom.c +++ b/src/PJ_gnom.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -111,27 +112,10 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(gnom) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; if (fabs(fabs(P->phi0) - M_HALFPI) < EPS10) { diff --git a/src/PJ_goode.c b/src/PJ_goode.c index 9138cedc..3bfeb21f 100644 --- a/src/PJ_goode.c +++ b/src/PJ_goode.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -43,42 +44,34 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ +static void *destructor (PJ *P, int errlev) { /* Destructor */ if (0==P) return 0; if (0==P->opaque) - return pj_dealloc(P); - if (P->opaque->sinu) - pj_free(P->opaque->sinu); - if (P->opaque->moll) - pj_free(P->opaque->moll); - pj_dealloc (P->opaque); - return pj_dealloc(P); - + return pj_default_destructor (P, errlev); + pj_free (P->opaque->sinu); + pj_free (P->opaque->moll); + return pj_default_destructor (P, errlev); } -static void freeup (PJ *P) { - freeup_new (P); - return; -} - PJ *PROJECTION(goode) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; + P->destructor = destructor; P->es = 0.; if (!(Q->sinu = pj_sinu(0)) || !(Q->moll = pj_moll(0))) - return freeup_new(P); + return destructor (P, ENOMEM); Q->sinu->es = 0.; - Q->sinu->ctx = P->ctx; - Q->moll->ctx = P->ctx; + Q->sinu->ctx = P->ctx; + Q->moll->ctx = P->ctx; if (!(Q->sinu = pj_sinu(Q->sinu)) || !(Q->moll = pj_moll(Q->moll))) - return freeup_new(P); - + return destructor (P, ENOMEM); + P->fwd = s_forward; P->inv = s_inverse; diff --git a/src/PJ_gstmerc.c b/src/PJ_gstmerc.c index a550ab2c..c2846761 100644 --- a/src/PJ_gstmerc.c +++ b/src/PJ_gstmerc.c @@ -1,5 +1,6 @@ #define PJ_LIB__ -#include <projects.h> +#include <errno.h> +#include "projects.h" PROJ_HEAD(gstmerc, "Gauss-Schreiber Transverse Mercator (aka Gauss-Laborde Reunion)") "\n\tCyl, Sph&Ell\n\tlat_0= lon_0= k_0="; @@ -46,27 +47,10 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(gstmerc) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->lamc = P->lam0; diff --git a/src/PJ_hammer.c b/src/PJ_hammer.c index 58182398..c18c9a69 100644 --- a/src/PJ_hammer.c +++ b/src/PJ_hammer.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -8,7 +9,7 @@ PROJ_HEAD(hammer, "Hammer & Eckert-Greifendorff") #define EPS 1.0e-10 struct pj_opaque { - double w; \ + double w; double m, rm; }; @@ -43,40 +44,20 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(hammer) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; if (pj_param(P->ctx, P->params, "tW").i) { - if ((Q->w = fabs(pj_param(P->ctx, P->params, "dW").f)) <= 0.) { - proj_errno_set(P, PJD_ERR_W_OR_M_ZERO_OR_LESS); - return freeup_new(P); - } + if ((Q->w = fabs(pj_param(P->ctx, P->params, "dW").f)) <= 0.) + return pj_default_destructor (P, PJD_ERR_W_OR_M_ZERO_OR_LESS); } else Q->w = .5; if (pj_param(P->ctx, P->params, "tM").i) { - if ((Q->m = fabs(pj_param(P->ctx, P->params, "dM").f)) <= 0.) { - proj_errno_set(P, PJD_ERR_W_OR_M_ZERO_OR_LESS); - return freeup_new(P); - } + if ((Q->m = fabs(pj_param(P->ctx, P->params, "dM").f)) <= 0.) + return pj_default_destructor (P, PJD_ERR_W_OR_M_ZERO_OR_LESS); } else Q->m = 1.; diff --git a/src/PJ_hatano.c b/src/PJ_hatano.c index d75a96a3..be95fe73 100644 --- a/src/PJ_hatano.c +++ b/src/PJ_hatano.c @@ -71,19 +71,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(hatano) { P->es = 0.; P->inv = s_inverse; @@ -110,10 +97,14 @@ int pj_hatano_selftest (void) { }; XY s_fwd_expect[] = { - { 189878.87894652804, 131409.8024406255
}, - { 189881.08195244463, -131409.14227607418
}, - {-189878.87894652804, 131409.8024406255
}, - {-189881.08195244463, -131409.14227607418
}, + { 189878.87894652804, 131409.8024406255 +}, + { 189881.08195244463, -131409.14227607418 +}, + {-189878.87894652804, 131409.8024406255 +}, + {-189881.08195244463, -131409.14227607418 +}, }; XY inv_in[] = { @@ -124,10 +115,14 @@ int pj_hatano_selftest (void) { }; LP s_inv_expect[] = { - { 0.0021064624821817597, 0.00076095689425791926
}, - { 0.0021064624821676096, -0.00076095777439265377
}, - {-0.0021064624821817597, 0.00076095689425791926
}, - {-0.0021064624821676096, -0.00076095777439265377
}, + { 0.0021064624821817597, 0.00076095689425791926 +}, + { 0.0021064624821676096, -0.00076095777439265377 +}, + {-0.0021064624821817597, 0.00076095689425791926 +}, + {-0.0021064624821676096, -0.00076095777439265377 +}, }; return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); diff --git a/src/PJ_healpix.c b/src/PJ_healpix.c index ef53e58f..241d7ef4 100644 --- a/src/PJ_healpix.c +++ b/src/PJ_healpix.c @@ -29,6 +29,7 @@ * SOFTWARE. *****************************************************************************/ # define PJ_LIB__ +# include <errno.h> # include <proj.h> # include "projects.h" @@ -598,30 +599,24 @@ static LP e_rhealpix_inverse(XY xy, PJ *P) { /* ellipsoid */ } -static void *freeup_new (PJ *P) { /* Destructor */ +static void *destructor (PJ *P, int errlev) { /* Destructor */ if (0==P) return 0; - if (0==P->opaque) - return pj_dealloc (P); - - if (P->opaque->apa) - pj_dealloc(P->opaque->apa); - pj_dealloc (P->opaque); - return pj_dealloc(P); -} + if (0==P->opaque) + return pj_default_destructor (P, errlev); -static void freeup (PJ *P) { - freeup_new (P); - return; + pj_dealloc (P->opaque->apa); + return pj_default_destructor (P, errlev); } PJ *PROJECTION(healpix) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; + P->destructor = destructor; if (P->es != 0.0) { Q->apa = pj_authset(P->es); /* For auth_lat(). */ @@ -642,21 +637,18 @@ PJ *PROJECTION(healpix) { PJ *PROJECTION(rhealpix) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; + P->destructor = destructor; Q->north_square = pj_param(P->ctx, P->params,"inorth_square").i; Q->south_square = pj_param(P->ctx, P->params,"isouth_square").i; /* Check for valid north_square and south_square inputs. */ - if (Q->north_square < 0 || Q->north_square > 3) { - proj_errno_set(P, PJD_ERR_AXIS); - return freeup_new(P); - } - if (Q->south_square < 0 || Q->south_square > 3) { - proj_errno_set(P, PJD_ERR_AXIS); - return freeup_new(P); - } + if (Q->north_square < 0 || Q->north_square > 3) + return destructor (P, PJD_ERR_AXIS); + if (Q->south_square < 0 || Q->south_square > 3) + return destructor (P, PJD_ERR_AXIS); if (P->es != 0.0) { Q->apa = pj_authset(P->es); /* For auth_lat(). */ Q->qp = pj_qsfn(1.0, P->e, P->one_es); /* For auth_lat(). */ diff --git a/src/PJ_helmert.c b/src/PJ_helmert.c index e291c189..ffbdd01a 100644 --- a/src/PJ_helmert.c +++ b/src/PJ_helmert.c @@ -43,12 +43,12 @@ Last update: 2017-05-15 ***********************************************************************/ #define PJ_LIB__ -#include "proj_internal.h" -#include <projects.h> -#include <geocent.h> #include <assert.h> #include <stddef.h> #include <errno.h> +#include "proj_internal.h" +#include "projects.h" +#include "geocent.h" PROJ_HEAD(helmert, "3(6)-, 4(8)- and 7(14)-parameter Helmert shift"); static XYZ helmert_forward_3d (LPZ lpz, PJ *P); @@ -56,28 +56,6 @@ static LPZ helmert_reverse_3d (XYZ xyz, PJ *P); -static void *freeup_msg (PJ *P, int errlev) { /* Destructor */ - if (0==P) - return 0; - - if (0!=P->ctx) - pj_ctx_set_errno (P->ctx, errlev); - - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -/* Adapts pipeline_freeup to the format defined for the PJ object */ -static void freeup (PJ *P) { - freeup_msg (P, 0); - return; -} - - /***********************************************************************/ struct pj_opaque_helmert { /************************************************************************ @@ -484,7 +462,7 @@ PJ *PROJECTION(helmert) { /***********************************************************************/ struct pj_opaque_helmert *Q = pj_calloc (1, sizeof (struct pj_opaque_helmert)); if (0==Q) - return freeup_msg (P, ENOMEM); + return pj_default_destructor (P, ENOMEM); P->opaque = (void *) Q; P->fwdobs = helmert_forward_obs; @@ -527,7 +505,7 @@ PJ *PROJECTION(helmert) { if (pj_param (P->ctx, P->params, "ts").i) { Q->scale_0 = pj_param (P->ctx, P->params, "ds").f; if (pj_param (P->ctx, P->params, "ttheta").i && Q->scale_0 == 0.0) - return freeup_msg(P, -PJD_ERR_INVALID_SCALE); + return pj_default_destructor (P, PJD_ERR_INVALID_SCALE); } /* Translation rates */ diff --git a/src/PJ_hgridshift.c b/src/PJ_hgridshift.c index 4ee3fd42..1b65b1bd 100644 --- a/src/PJ_hgridshift.c +++ b/src/PJ_hgridshift.c @@ -1,25 +1,9 @@ #define PJ_LIB__ #include "proj_internal.h" -#include <projects.h> +#include "projects.h" PROJ_HEAD(hgridshift, "Horizontal grid shift"); -static void *freeup_msg (PJ *P, int errlev) { - if (0==P) - return 0; - - if (0!=P->ctx) - pj_ctx_set_errno (P->ctx, errlev); - - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_msg (P, 0); - return; -} - static XYZ forward_3d(LPZ lpz, PJ *P) { PJ_TRIPLET point; @@ -67,25 +51,30 @@ static PJ_OBS reverse_obs(PJ_OBS obs, PJ *P) { } -PJ *PROJECTION(hgridshift) { - if (!pj_param(P->ctx, P->params, "tgrids").i) { - proj_log_error(P, "hgridshift: +grids parameter missing."); - return freeup_msg(P, -1); - } +#if 0 +static XY forward_xy(LP lp, PJ *P) { + PJ_TRIPLET point; + point.lp = lp; + point.lpz.z = 0; + point.xyz = forward_3d (point.lpz, P); + return point.xy; +} - /* Build gridlist. P->gridlist can be empty if +grids only ask for optional grids. */ - P->gridlist = pj_gridlist_from_nadgrids( P->ctx, pj_param(P->ctx, P->params, "sgrids").s, - &(P->gridlist_count) ); - /* Was gridlist compiled properly? */ - if ( pj_ctx_get_errno(P->ctx) ) { - proj_log_error(P, "hgridshift: could not find required grid(s)."); - pj_dalloc(P->gridlist); - P->gridlist = NULL; - return freeup_msg(P, -38); - } +static LP reverse_lp(XY xy, PJ *P) { + PJ_TRIPLET point; + point.xy = xy; + point.xyz.z = 0; + point.lpz = reverse_3d (point.xyz, P); + return point.lp; +} +#endif + + +PJ *PROJECTION(hgridshift) { + P->fwdobs = forward_obs; P->invobs = reverse_obs; P->fwd3d = forward_3d; @@ -96,6 +85,21 @@ PJ *PROJECTION(hgridshift) { P->left = PJ_IO_UNITS_RADIANS; P->right = PJ_IO_UNITS_RADIANS; + if (0==pj_param(P->ctx, P->params, "tgrids").i) { + proj_log_error(P, "hgridshift: +grids parameter missing."); + return pj_default_destructor (P, PJD_ERR_NO_ARGS); + } + + /* Build gridlist. P->gridlist can be empty if +grids only ask for optional grids. */ + P->gridlist = pj_gridlist_from_nadgrids( P->ctx, pj_param(P->ctx, P->params, "sgrids").s, + &(P->gridlist_count) ); + + /* Was gridlist compiled properly? */ + if ( pj_ctx_get_errno(pj_get_ctx(P)) ) { + proj_log_error(P, "hgridshift: could not find required grid(s)."); + return pj_default_destructor (P, PJD_ERR_FAILED_TO_LOAD_GRID); + } + return P; } @@ -111,24 +115,27 @@ int pj_hgridshift_selftest (void) { /* fail on purpose: +grids parameter is mandatory*/ P = proj_create(PJ_DEFAULT_CTX, "+proj=hgridshift"); - if (0!=P) + if (0!=P) { + proj_destroy (P); return 99; - + } + /* fail on purpose: open non-existing grid */ - P = proj_create(PJ_DEFAULT_CTX, "+proj=hgridshift +grids=nonexistinggrid.gsb"); - if (0!=P) + P = proj_create(PJ_DEFAULT_CTX, "+proj=hgridshift +grids=@nonexistinggrid.gsb,anothernonexistinggrid.gsb"); + if (0!=P) { + proj_destroy (P); return 999; - - + } + /* Failure most likely means the grid is missing */ P = proj_create(PJ_DEFAULT_CTX, "+proj=hgridshift +grids=nzgd2kgrid0005.gsb +ellps=GRS80"); if (0==P) return 10; - + a = proj_obs_null; a.coo.lpz.lam = PJ_TORAD(173); a.coo.lpz.phi = PJ_TORAD(-45); - + dist = proj_roundtrip (P, PJ_FWD, 1, a); if (dist > 0.00000001) return 1; diff --git a/src/PJ_horner.c b/src/PJ_horner.c index a9a618c7..c29cdcd0 100644 --- a/src/PJ_horner.c +++ b/src/PJ_horner.c @@ -1,6 +1,6 @@ #define PJ_LIB__ #include "proj_internal.h" -#include <projects.h> +#include "projects.h" #include <assert.h> #include <stddef.h> #include <math.h> @@ -382,18 +382,14 @@ static PJ_OBS complex_horner_reverse_obs (PJ_OBS point, PJ *P) { } -static void *horner_freeup (PJ *P) { /* Destructor */ +static void *horner_freeup (PJ *P, int errlev) { /* Destructor */ if (0==P) return 0; if (0==P->opaque) - return pj_dealloc (P); + return pj_default_destructor (P, errlev); horner_free ((HORNER *) P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - horner_freeup (P); - return; + P->opaque = 0; + return pj_default_destructor (P, errlev); } @@ -442,13 +438,14 @@ PJ *PROJECTION(horner) { P->fwd = 0; P->inv = 0; P->left = P->right = PJ_IO_UNITS_METERS; + P->destructor = horner_freeup; /* Polynomial degree specified? */ if (pj_param (P->ctx, P->params, "tdeg").i) /* degree specified? */ degree = pj_param(P->ctx, P->params, "ideg").i; else { proj_log_debug (P, "Horner: Must specify polynomial degree, (+deg=n)"); - return horner_freeup (P); + return horner_freeup (P, PJD_ERR_MISSING_ARGS); } if (pj_param (P->ctx, P->params, "tfwd_c").i || pj_param (P->ctx, P->params, "tinv_c").i) /* complex polynomium? */ @@ -456,17 +453,15 @@ PJ *PROJECTION(horner) { Q = horner_alloc (degree, complex_horner); if (Q == 0) - { - return horner_freeup (P); - } + return horner_freeup (P, ENOMEM); P->opaque = (void *) Q; if (complex_horner) { n = 2*degree + 2; if (0==parse_coefs (P, Q->fwd_c, "fwd_c", n)) - return horner_freeup (P); + return horner_freeup (P, PJD_ERR_MISSING_ARGS); if (0==parse_coefs (P, Q->inv_c, "inv_c", n)) - return horner_freeup (P); + return horner_freeup (P, PJD_ERR_MISSING_ARGS); P->fwdobs = complex_horner_forward_obs; P->invobs = complex_horner_reverse_obs; @@ -474,19 +469,19 @@ PJ *PROJECTION(horner) { else { n = horner_number_of_coefficients (degree); if (0==parse_coefs (P, Q->fwd_u, "fwd_u", n)) - return horner_freeup (P); + return horner_freeup (P, PJD_ERR_MISSING_ARGS); if (0==parse_coefs (P, Q->fwd_v, "fwd_v", n)) - return horner_freeup (P); + return horner_freeup (P, PJD_ERR_MISSING_ARGS); if (0==parse_coefs (P, Q->inv_u, "inv_u", n)) - return horner_freeup (P); + return horner_freeup (P, PJD_ERR_MISSING_ARGS); if (0==parse_coefs (P, Q->inv_v, "inv_v", n)) - return horner_freeup (P); + return horner_freeup (P, PJD_ERR_MISSING_ARGS); } if (0==parse_coefs (P, (double *)(Q->fwd_origin), "fwd_origin", 2)) - return horner_freeup (P); + return horner_freeup (P, PJD_ERR_MISSING_ARGS); if (0==parse_coefs (P, (double *)(Q->inv_origin), "inv_origin", 2)) - return horner_freeup (P); + return horner_freeup (P, PJD_ERR_MISSING_ARGS); if (0==parse_coefs (P, &Q->range, "range", 1)) Q->range = 500000; diff --git a/src/PJ_igh.c b/src/PJ_igh.c index 9b5f7075..33cdde22 100644 --- a/src/PJ_igh.c +++ b/src/PJ_igh.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include "projects.h" PROJ_HEAD(igh, "Interrupted Goode Homolosine") "\n\tPCyl, Sph."; @@ -130,26 +131,20 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ +static void *destructor (PJ *P, int errlev) { int i; if (0==P) return 0; + if (0==P->opaque) - return pj_dealloc (P); + return pj_default_destructor (P, errlev); for (i = 0; i < 12; ++i) { if (P->opaque->pj[i]) - P->opaque->pj[i]->pfree(P->opaque->pj[i]); + P->opaque->pj[i]->destructor(P->opaque->pj[i], errlev); } - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; + return pj_default_destructor(P, errlev); } @@ -175,8 +170,8 @@ static void freeup (PJ *P) { */ #define SETUP(n, proj, x_0, y_0, lon_0) \ - if (!(Q->pj[n-1] = pj_##proj(0))) return freeup_new(P); \ - if (!(Q->pj[n-1] = pj_##proj(Q->pj[n-1]))) return freeup_new(P); \ + if (!(Q->pj[n-1] = pj_##proj(0))) return destructor(P, ENOMEM); \ + if (!(Q->pj[n-1] = pj_##proj(Q->pj[n-1]))) return destructor(P, ENOMEM); \ Q->pj[n-1]->ctx = P->ctx; \ Q->pj[n-1]->x0 = x_0; \ Q->pj[n-1]->y0 = y_0; \ @@ -188,7 +183,7 @@ PJ *PROJECTION(igh) { LP lp = { 0, d4044118 }; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -220,6 +215,7 @@ PJ *PROJECTION(igh) { P->inv = s_inverse; P->fwd = s_forward; + P->destructor = destructor; P->es = 0.; return P; diff --git a/src/PJ_imw_p.c b/src/PJ_imw_p.c index 0b2a6602..29ed3457 100644 --- a/src/PJ_imw_p.c +++ b/src/PJ_imw_p.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -130,36 +131,31 @@ static void xy(PJ *P, double phi, double *x, double *y, double *sp, double *R) { } -static void *freeup_new (PJ *P) { /* Destructor */ +static void *destructor (PJ *P, int errlev) { if (0==P) return 0; + if (0==P->opaque) - return pj_dealloc (P); + return pj_default_destructor (P, errlev); if( P->opaque->en ) pj_dealloc (P->opaque->en); - pj_dealloc (P->opaque); - return pj_dealloc(P); -} -static void freeup (PJ *P) { - freeup_new (P); - return; + return pj_default_destructor(P, errlev); } PJ *PROJECTION(imw_p) { double del, sig, s, t, x1, x2, T2, y1, m1, m2, y2; - int i; + int err; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; - if (!(Q->en = pj_enfn(P->es))) return freeup_new(P); - if( (i = phi12(P, &del, &sig)) != 0) { - proj_errno_set(P, i); - return freeup_new(P); + if (!(Q->en = pj_enfn(P->es))) return pj_default_destructor (P, ENOMEM); + if( (err = phi12(P, &del, &sig)) != 0) { + return destructor(P, err); } if (Q->phi_2 < Q->phi_1) { /* make sure P->phi_1 most southerly */ del = Q->phi_1; @@ -204,6 +200,7 @@ PJ *PROJECTION(imw_p) { P->fwd = e_forward; P->inv = e_inverse; + P->destructor = destructor; return P; } diff --git a/src/PJ_isea.c b/src/PJ_isea.c index deaecb0f..223d8f28 100644 --- a/src/PJ_isea.c +++ b/src/PJ_isea.c @@ -1034,6 +1034,7 @@ isea_forward(struct isea_dgg *g, struct isea_geo *in) */ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -1062,27 +1063,11 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(isea) { char *opt; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -1100,8 +1085,7 @@ PJ *PROJECTION(isea) { } else if (!strcmp(opt, "pole")) { isea_orient_pole(&Q->dgg); } else { - proj_errno_set(P, PJD_ERR_ELLIPSOID_USE_REQUIRED); - return freeup_new(P); + return pj_default_destructor(P, PJD_ERR_ELLIPSOID_USE_REQUIRED); } } @@ -1140,8 +1124,7 @@ PJ *PROJECTION(isea) { } else { /* TODO verify error code. Possibly eliminate magic */ - proj_errno_set(P, PJD_ERR_ELLIPSOID_USE_REQUIRED); - return freeup_new(P); + return pj_default_destructor(P, PJD_ERR_ELLIPSOID_USE_REQUIRED); } } diff --git a/src/PJ_krovak.c b/src/PJ_krovak.c index bee66b07..640ce07f 100644 --- a/src/PJ_krovak.c +++ b/src/PJ_krovak.c @@ -77,7 +77,8 @@ #define PJ_LIB__ -#include <projects.h> +#include <errno.h> +#include "projects.h" PROJ_HEAD(krovak, "Krovak") "\n\tPCyl., Ellps."; @@ -173,27 +174,11 @@ static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc(P); - - pj_dealloc(P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(krovak) { double u0, n0, g; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; /* we want Bessel as fixed ellipsoid */ diff --git a/src/PJ_labrd.c b/src/PJ_labrd.c index dfc54478..4b5d93a5 100644 --- a/src/PJ_labrd.c +++ b/src/PJ_labrd.c @@ -1,5 +1,6 @@ #define PJ_LIB__ -#include <projects.h> +#include <errno.h> +#include "projects.h" PROJ_HEAD(labrd, "Laborde") "\n\tCyl, Sph\n\tSpecial for Madagascar"; #define EPS 1.e-10 @@ -95,28 +96,11 @@ static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(labrd) { double Az, sinp, R, N, t; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->rot = pj_param(P->ctx, P->params, "bno_rot").i == 0; diff --git a/src/PJ_laea.c b/src/PJ_laea.c index 0a638fb0..ddca63d9 100644 --- a/src/PJ_laea.c +++ b/src/PJ_laea.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -219,20 +220,16 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ +static void *destructor (PJ *P, int errlev) { if (0==P) return 0; + if (0==P->opaque) - return pj_dealloc (P); + return pj_default_destructor (P, errlev); pj_dealloc (P->opaque->apa); - pj_dealloc (P->opaque); - return pj_dealloc(P); -} -static void freeup (PJ *P) { - freeup_new (P); - return; + return pj_default_destructor(P, errlev); } @@ -240,8 +237,9 @@ PJ *PROJECTION(laea) { double t; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; + P->destructor = destructor; t = fabs(P->phi0); if (fabs(t - M_HALFPI) < EPS10) diff --git a/src/PJ_lagrng.c b/src/PJ_lagrng.c index 98500900..e30f6a36 100644 --- a/src/PJ_lagrng.c +++ b/src/PJ_lagrng.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -35,42 +36,22 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(lagrng) { double phi1; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->rw = pj_param(P->ctx, P->params, "dW").f; - if (Q->rw <= 0) { - proj_errno_set(P, PJD_ERR_W_OR_M_ZERO_OR_LESS); - return freeup_new(P); - } + if (Q->rw <= 0) + return pj_default_destructor(P, PJD_ERR_W_OR_M_ZERO_OR_LESS); Q->rw = 1. / Q->rw; Q->hrw = 0.5 * Q->rw; phi1 = sin(pj_param(P->ctx, P->params, "rlat_1").f); - if (fabs(fabs(phi1) - 1.) < TOL) { - proj_errno_set(P, PJD_ERR_LAT_LARGER_THAN_90); - return freeup_new(P); - } + if (fabs(fabs(phi1) - 1.) < TOL) + return pj_default_destructor(P, PJD_ERR_LAT_LARGER_THAN_90); Q->a1 = pow((1. - phi1)/(1. + phi1), Q->hrw); diff --git a/src/PJ_larr.c b/src/PJ_larr.c index dba2534c..cd6e6c8a 100644 --- a/src/PJ_larr.c +++ b/src/PJ_larr.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -#include <projects.h> +#include "projects.h" PROJ_HEAD(larr, "Larrivee") "\n\tMisc Sph, no inv."; @@ -16,20 +16,6 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(larr) { P->es = 0; diff --git a/src/PJ_lask.c b/src/PJ_lask.c index 9aa96206..d0efeb7d 100644 --- a/src/PJ_lask.c +++ b/src/PJ_lask.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -#include <projects.h> +#include "projects.h" PROJ_HEAD(lask, "Laskowski") "\n\tMisc Sph, no inv."; @@ -28,19 +28,6 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ return xy; } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - PJ *PROJECTION(lask) { diff --git a/src/pj_latlong.c b/src/PJ_latlong.c index 761eadc5..dec69b70 100644 --- a/src/pj_latlong.c +++ b/src/PJ_latlong.c @@ -53,19 +53,6 @@ static LP inverse(XY xy, PJ *P) { } -static void *freeup_new (PJ *P) { - if (0==P) - return 0; - - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(latlong) { P->is_latlong = 1; P->x0 = 0.0; diff --git a/src/PJ_lcc.c b/src/PJ_lcc.c index 905f7086..78c227b8 100644 --- a/src/PJ_lcc.c +++ b/src/PJ_lcc.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -88,29 +89,13 @@ static void special(LP lp, PJ *P, struct FACTORS *fac) { } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(lcc) { double cosphi, sinphi; int secant; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -122,10 +107,9 @@ PJ *PROJECTION(lcc) { if (!pj_param(P->ctx, P->params, "tlat_0").i) P->phi0 = Q->phi1; } - if (fabs(Q->phi1 + Q->phi2) < EPS10) { - proj_errno_set(P, PJD_ERR_CONIC_LAT_EQUAL); - return freeup_new(P); - } + if (fabs(Q->phi1 + Q->phi2) < EPS10) + return pj_default_destructor(P, PJD_ERR_CONIC_LAT_EQUAL); + Q->n = sinphi = sin(Q->phi1); cosphi = cos(Q->phi1); secant = fabs(Q->phi1 - Q->phi2) >= EPS10; diff --git a/src/PJ_lcca.c b/src/PJ_lcca.c index 77704375..7d1355b9 100644 --- a/src/PJ_lcca.c +++ b/src/PJ_lcca.c @@ -1,6 +1,7 @@ /* PROJ.4 Cartographic Projection System */ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -69,20 +70,15 @@ static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ +static void *destructor (PJ *P, int errlev) { if (0==P) return 0; + if (0==P->opaque) - return pj_dealloc (P); + return pj_default_destructor (P, errlev); pj_dealloc (P->opaque->en); - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; + return pj_default_destructor (P, errlev); } @@ -90,16 +86,15 @@ PJ *PROJECTION(lcca) { double s2p0, N0, R0, tan0; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; (Q->en = pj_enfn(P->es)); if (!Q->en) - return freeup_new(P); + return pj_default_destructor (P, ENOMEM); if (P->phi0 == 0.) { - proj_errno_set(P, PJD_ERR_LAT_0_IS_ZERO); - return freeup_new(P); + return destructor(P, PJD_ERR_LAT_0_IS_ZERO); } Q->l = sin(P->phi0); Q->M0 = pj_mlfn(P->phi0, Q->l, cos(P->phi0), Q->en); @@ -113,6 +108,7 @@ PJ *PROJECTION(lcca) { P->inv = e_inverse; P->fwd = e_forward; + P->destructor = destructor; return P; } diff --git a/src/PJ_loxim.c b/src/PJ_loxim.c index 6cd56eef..a4ae074b 100644 --- a/src/PJ_loxim.c +++ b/src/PJ_loxim.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -49,34 +50,17 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(loxim) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->phi1 = pj_param(P->ctx, P->params, "rlat_1").f; Q->cosphi1 = cos(Q->phi1); - if (Q->cosphi1 < EPS) { - proj_errno_set(P, PJD_ERR_LAT_LARGER_THAN_90); - return freeup_new(P); - } + if (Q->cosphi1 < EPS) + return pj_default_destructor(P, PJD_ERR_LAT_LARGER_THAN_90); + Q->tanphi1 = tan(M_FORTPI + 0.5 * Q->phi1); diff --git a/src/PJ_lsat.c b/src/PJ_lsat.c index 15009d61..1b3778d6 100644 --- a/src/PJ_lsat.c +++ b/src/PJ_lsat.c @@ -1,5 +1,6 @@ /* based upon Snyder and Linck, USGS-NMD */ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -148,40 +149,22 @@ static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(lsat) { int land, path; double lam, alf, esc, ess; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; land = pj_param(P->ctx, P->params, "ilsat").i; - if (land <= 0 || land > 5) { - proj_errno_set(P, PJD_ERR_LSAT_NOT_IN_RANGE); - return freeup_new(P); - } + if (land <= 0 || land > 5) + return pj_default_destructor(P, PJD_ERR_LSAT_NOT_IN_RANGE); + path = pj_param(P->ctx, P->params, "ipath").i; - if (path <= 0 || path > (land <= 3 ? 251 : 233)) { - proj_errno_set(P, PJD_ERR_PATH_NOT_IN_RANGE); - return freeup_new(P); - } + if (path <= 0 || path > (land <= 3 ? 251 : 233)) + pj_default_destructor(P, PJD_ERR_PATH_NOT_IN_RANGE); + if (land <= 3) { P->lam0 = DEG_TO_RAD * 128.87 - M_TWOPI / 251. * path; Q->p22 = 103.2669323; diff --git a/src/PJ_mbt_fps.c b/src/PJ_mbt_fps.c index 5a3f3774..c35da04c 100644 --- a/src/PJ_mbt_fps.c +++ b/src/PJ_mbt_fps.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -#include <projects.h> +#include "projects.h" PROJ_HEAD(mbt_fps, "McBryde-Thomas Flat-Pole Sine (No. 2)") "\n\tCyl., Sph."; @@ -44,20 +44,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(mbt_fps) { P->es = 0; diff --git a/src/PJ_mbtfpp.c b/src/PJ_mbtfpp.c index f8a5e807..2bbb16b1 100644 --- a/src/PJ_mbtfpp.c +++ b/src/PJ_mbtfpp.c @@ -52,19 +52,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(mbtfpp) { P->es = 0.; diff --git a/src/PJ_mbtfpq.c b/src/PJ_mbtfpq.c index b6910a45..4901401e 100644 --- a/src/PJ_mbtfpq.c +++ b/src/PJ_mbtfpq.c @@ -61,19 +61,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(mbtfpq) { P->es = 0.; diff --git a/src/PJ_merc.c b/src/PJ_merc.c index 04e5dc21..d17a2d50 100644 --- a/src/PJ_merc.c +++ b/src/PJ_merc.c @@ -49,22 +49,14 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void freeup(PJ *P) { /* Destructor */ - pj_dealloc(P); -} - - PJ *PROJECTION(merc) { double phits=0.0; int is_phits; if( (is_phits = pj_param(P->ctx, P->params, "tlat_ts").i) ) { phits = fabs(pj_param(P->ctx, P->params, "rlat_ts").f); - if (phits >= M_HALFPI) { - proj_errno_set(P, PJD_ERR_LAT_TS_LARGER_THAN_90); - freeup(P); - return 0; - } + if (phits >= M_HALFPI) + return pj_default_destructor(P, PJD_ERR_LAT_TS_LARGER_THAN_90); } if (P->es != 0.0) { /* ellipsoid */ diff --git a/src/PJ_mill.c b/src/PJ_mill.c index 17763410..829bc3be 100644 --- a/src/PJ_mill.c +++ b/src/PJ_mill.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -#include <projects.h> +#include "projects.h" PROJ_HEAD(mill, "Miller Cylindrical") "\n\tCyl, Sph"; @@ -25,19 +25,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(mill) { P->es = 0.; P->inv = s_inverse; diff --git a/src/PJ_minimal.c b/src/PJ_minimal.c deleted file mode 100644 index 1108c4fa..00000000 --- a/src/PJ_minimal.c +++ /dev/null @@ -1,204 +0,0 @@ -/*********************************************************************** - - A minimal example of a new proj.4 projection implementation - - ...and a verbose justification for some highly intrusive code - surgery - -************************************************************************ - -**The brief version:** - -In an attempt to make proj.4 code slightly more secure and much easier -to read and maintain, I'm trying to eliminate a few unfortunate design -decisions from the early days of proj.4 - -The work will be *very* intrusive, especially in the PJ_xxx segment of -the code tree, but great care has been taken to design a process that -can be implemented stepwise and localized, one projection at a time, -then finalized with a relatively small and concentrated work package. - -**The (very) long version:** - -Gerald I. Evenden's original design for the proj.4 projection system -is a beautiful example of software architecture, where a very limited -set of policy rules leads to a well defined hierarchical structure and -a high degree of both encapsulation and internal interoperability. - -In the proj.4 code, the policy rules are *enforced* by a system of -preprocessor macros for building the scaffolding for implementation -of a new projection. - -While this system of macros undeniably possesses the property of both -reducing repetitive code and enforcing policy, unfortunately it also -possesses two much less desirable properties: - -First, while enforcing policy, it also *hides* policy: The "beauty in -simplicity" of Gerald's design is hidden behind layers of macros, -whose architectural clarity do not match that of proj.4 in general. - -Second (and related), the macros make the source code look like -something only vaguely related to C, making it hard to read (an effect -that gets amplified to the tune of syntax highlighters getting confused -by the macros). - -While the policy rule enforcement macros can be eliminated in relatively -non-intrusive ways, a more fundamental flaw in the proj.4 use of macros -is found in the PJ_xxx.c files implementing the individual projections: -The use of internal redefinition of PJ, the fundamental proj data object, -through the use of the PROJ_PARMS__ macro, makes the sizeof (PJ) -fundamentally unknown to the calling pj_init function. - -This leads to code that is probably not in full conformance with the -C standard. - -It is also a memory management catastrophe waiting to happen. - -But first and foremost, it leads to some very clumsy initialization code, -where pj_init (the constructor function), needs to start the constsruction -process by asking the PJ_xxx function to do the memory allocation (because -pj_init does not know the size of the PROJ_PARMS-mangled PJ object being -instantiated). - -Then, after doing some initialization work, pj_init returns control to -PJ_xxx, asking it to finalize the initialization with the projection -specific parameters specified by the PROJ_PARMS__ macro. - -Behind the scenes, hidden by two layers of macros, what happens is even -worse, as a lot of the initialization code is duplicated in every PJ_xxx -file, rather than being centralized in the pj_init function. - -**Solution procedure:** - -Evidently, the way to eliminate this clumsyness will be to introduce an -opaque object, that is managed by tne individual PJ_xxx projection code, -and represented as a simple void-pointer in the PJ object. - -This can be done one projection code file at a time, working through the -code base as time permits (it will take at least a month). - -When a PJ_xxx file is on the surgical bench, it will also have its -ENTRYA/ENTRY0/ENTRY1/ENTRY2/ENDENTRY/etc. etc. macro-guts torn out and -replaced by the PROJECTION macro (introduced in projects.h). - -This leads to code that looks a lot more like real C, and hence is much -less confusing to both syntax higlighters and humans. It also leads -to code that, after all projections have been processed, with a final -sweep over the code base can be brought into the style of the code in -PJ_minimal.c - -In my humble opinion the result wil be a code base that is not only easier -to maintain, but also more welcoming to new contributors. - -And if proj is to expand its strong basis in projections into the fields -of geodetic transformations and general geometric geodesy, we will need -to be able to attract quite a few expert geodesist contributors. - -And since expert geodesists are not necessarily expert coders, a welcoming -code base is a real asset (to put the icing on the cake of the already -welcoming user- and developer community). - -Note that the entire process does not touch the algorithmic/mathematical -parts of the code at all - it is actuallly an attempt to make this part -stand out more clearly. - ---- - -The attached material is an attempt to show what happens if we remove -the layers of macros, and introduce a more centralized approach to -memory allocation and initialization. - -Please note, however, that the level of cantralization achieved here -is not yet fully supported by the proj.4 infrastructure: It is an -example, intended to show what can be achieved through a smooth, -gradual and safe refactoring of the existing layered macro system. - -In my humble opinion, this version makes the beauty of Gerald's design -much more evident than the current layered-macro-version. - -Thomas Knudsen, thokn@sdfe.dk, 2016-03-31 - -***********************************************************************/ - -#define PJ_LIB__ -#include <projects.h> -#include <assert.h> -PROJ_HEAD(minimal, "Minimal example (brief description goes here)"); - - -/* Projection specific elements for the PJ object */ -struct pj_opaque { - double a; - int b; -}; - - -static XY e_forward (LP lp, PJ *P) { /* Ellipsoidal, forward */ - XY xy = {0.0,0.0}; - /* Actual ellipsoidal forward code goes here */ - xy.y = lp.lam + P->es; - xy.x = lp.phi + 42; - return xy; -} - - -static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ - XY xy = {0.0,0.0}; - /* Actual spheroidal forward code goes here */ - xy.y = lp.lam + P->es; - xy.x = lp.phi + 42; - return xy; -} - - -static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ - LP lp = {0.0,0.0}; - /* Actual ellipsoidal forward code goes here */ - lp.lam = xy.x - P->es; - lp.phi = xy.y - P->opaque->b; - return lp; -} - - -static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ - LP lp = {0.0,0.0}; - /* Actual spheroidal forward code goes here */ - lp.lam = xy.x - P->es; - lp.phi = xy.y - P->opaque->b; - return lp; -} - - -static void freeup(PJ *P) { /* Destructor */ - if (P==0) - return; - /* Projection specific deallocation goes here */ - pj_dealloc (P->opaque); - pj_dealloc (P); - return; -} - - -PJ *pj_projection_specific_setup_minimal (PJ *P) { - pj_prepare (P, des_minimal, freeup, sizeof (struct pj_opaque)); - if (0==P->opaque) { - freeup (P); - return 0; - } - - P->opaque->a = 42.42; - P->opaque->b = 42; - - /* Spheroidal? */ - if (0==P->es) { - P->fwd = s_forward; - P->inv = s_inverse; - return P; - } - - /* Otherwise it's ellipsoidal */ - P->fwd = e_forward; - P->inv = e_inverse; - - return P; -} diff --git a/src/PJ_misrsom.c b/src/PJ_misrsom.c index 49be1669..5c5a226f 100644 --- a/src/PJ_misrsom.c +++ b/src/PJ_misrsom.c @@ -21,6 +21,7 @@ *****************************************************************************/ /* based upon Snyder and Linck, USGS-NMD */ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -164,36 +165,19 @@ static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(misrsom) { int path; double lam, alf, esc, ess; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; path = pj_param(P->ctx, P->params, "ipath").i; - if (path <= 0 || path > 233) { - proj_errno_set(P, PJD_ERR_PATH_NOT_IN_RANGE); - return freeup_new(P); - } + if (path <= 0 || path > 233) + return pj_default_destructor(P, PJD_ERR_PATH_NOT_IN_RANGE); + P->lam0 = DEG_TO_RAD * 129.3056 - M_TWOPI / 233. * path; alf = 98.30382 * DEG_TO_RAD; Q->p22 = 98.88 / 1440.0; diff --git a/src/PJ_mod_ster.c b/src/PJ_mod_ster.c index f8c90bc4..767863c1 100644 --- a/src/PJ_mod_ster.c +++ b/src/PJ_mod_ster.c @@ -1,6 +1,7 @@ /* based upon Snyder and Linck, USGS-NMD */ #define PJ_LIB__ -#include <projects.h> +#include <errno.h> +#include "projects.h" PROJ_HEAD(mil_os, "Miller Oblated Stereographic") "\n\tAzi(mod)"; PROJ_HEAD(lee_os, "Lee Oblated Stereographic") "\n\tAzi(mod)"; @@ -98,21 +99,6 @@ static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - static PJ *setup(PJ *P) { /* general initialization */ struct pj_opaque *Q = P->opaque; double esphi, chio; @@ -142,7 +128,7 @@ PJ *PROJECTION(mil_os) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->n = 2; @@ -165,7 +151,7 @@ PJ *PROJECTION(lee_os) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->n = 2; @@ -190,7 +176,7 @@ PJ *PROJECTION(gs48) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->n = 4; @@ -225,7 +211,7 @@ PJ *PROJECTION(alsk) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->n = 5; @@ -273,7 +259,7 @@ PJ *PROJECTION(gs50) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->n = 9; diff --git a/src/PJ_moll.c b/src/PJ_moll.c index b975cc73..8470bb3e 100644 --- a/src/PJ_moll.c +++ b/src/PJ_moll.c @@ -1,5 +1,6 @@ #define PJ_LIB__ -#include <projects.h> +#include <errno.h> +#include "projects.h" PROJ_HEAD(moll, "Mollweide") "\n\tPCyl., Sph."; PROJ_HEAD(wag4, "Wagner IV") "\n\tPCyl., Sph."; @@ -51,23 +52,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - static PJ * setup(PJ *P, double p) { struct pj_opaque *Q = P->opaque; double r, sp, p2 = p + p; @@ -89,7 +73,7 @@ static PJ * setup(PJ *P, double p) { PJ *PROJECTION(moll) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; return setup(P, M_HALFPI); @@ -99,7 +83,7 @@ PJ *PROJECTION(moll) { PJ *PROJECTION(wag4) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; return setup(P, M_PI/3.); @@ -108,7 +92,7 @@ PJ *PROJECTION(wag4) { PJ *PROJECTION(wag5) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; P->es = 0; diff --git a/src/PJ_molodensky.c b/src/PJ_molodensky.c index d9377234..fc68ee50 100644 --- a/src/PJ_molodensky.c +++ b/src/PJ_molodensky.c @@ -63,27 +63,6 @@ struct pj_opaque_molodensky { }; -static void *freeup_msg(PJ *P, int errlev) { - if (0==P) - return 0; - - if (0!=P->ctx) - pj_ctx_set_errno (P->ctx, errlev); - - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - - return pj_dealloc(P); -} - -static void freeup(PJ *P) { - freeup_msg (P, 0); - return; -} - - static double RN (double a, double es, double phi) { /********************************************************** N(phi) - prime vertical radius of curvature @@ -287,7 +266,7 @@ static PJ_OBS reverse_obs(PJ_OBS obs, PJ *P) { PJ *PROJECTION(molodensky) { struct pj_opaque_molodensky *Q = pj_calloc(1, sizeof(struct pj_opaque_molodensky)); if (0==Q) - return freeup_msg(P, ENOMEM); + return pj_default_destructor(P, ENOMEM); P->opaque = (void *) Q; P->fwdobs = forward_obs; @@ -320,10 +299,10 @@ PJ *PROJECTION(molodensky) { /* We want all parameters (except +abridged) to be set */ if ((Q->dx == 0) && (Q->dy == 0) && (Q->dz == 0) && (Q->da == 0) && (Q->df == 0)) - return freeup_msg(P, PJD_ERR_NO_ARGS); + return pj_default_destructor(P, PJD_ERR_NO_ARGS); if ((Q->dx == 0) || (Q->dy == 0) || (Q->dz == 0) || (Q->da == 0) || (Q->df == 0)) - return freeup_msg(P, PJD_ERR_MISSING_ARGS); + return pj_default_destructor(P, PJD_ERR_MISSING_ARGS); return P; } diff --git a/src/PJ_natearth.c b/src/PJ_natearth.c index 8d0dae08..9c40f3da 100644 --- a/src/PJ_natearth.c +++ b/src/PJ_natearth.c @@ -13,7 +13,7 @@ and designed in collaboration with Tom Patterson. Port to PROJ.4 by Bernhard Jenny, 6 June 2011 */ #define PJ_LIB__ -#include <projects.h> +#include "projects.h" PROJ_HEAD(natearth, "Natural Earth") "\n\tPCyl., Sph."; @@ -88,20 +88,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(natearth) { P->es = 0; P->inv = s_inverse; diff --git a/src/PJ_natearth2.c b/src/PJ_natearth2.c index aab9f9ac..95bb8646 100644 --- a/src/PJ_natearth2.c +++ b/src/PJ_natearth2.c @@ -6,7 +6,7 @@ and Atmospheric Sciences, Oregon State University. Port to PROJ.4 by Bojan Savric, 4 April 2016 */ #define PJ_LIB__ -#include <projects.h> +#include "projects.h" PROJ_HEAD(natearth2, "Natural Earth 2") "\n\tPCyl., Sph."; @@ -85,20 +85,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(natearth2) { P->es = 0; P->inv = s_inverse; diff --git a/src/PJ_nell.c b/src/PJ_nell.c index 1b6af010..ac071fc9 100644 --- a/src/PJ_nell.c +++ b/src/PJ_nell.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -#include <projects.h> +#include "projects.h" PROJ_HEAD(nell, "Nell") "\n\tPCyl., Sph."; @@ -38,20 +38,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(nell) { P->es = 0; diff --git a/src/PJ_nell_h.c b/src/PJ_nell_h.c index dfad72b2..fe9a75c6 100644 --- a/src/PJ_nell_h.c +++ b/src/PJ_nell_h.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -#include <projects.h> +#include "projects.h" PROJ_HEAD(nell_h, "Nell-Hammer") "\n\tPCyl., Sph."; @@ -41,20 +41,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(nell_h) { P->es = 0.; P->inv = s_inverse; diff --git a/src/PJ_nocol.c b/src/PJ_nocol.c index 88836a10..934ba7ab 100644 --- a/src/PJ_nocol.c +++ b/src/PJ_nocol.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -#include <projects.h> +#include "projects.h" PROJ_HEAD(nicol, "Nicolosi Globular") "\n\tMisc Sph, no inv."; @@ -43,20 +43,6 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(nicol) { P->es = 0.; P->fwd = s_forward; diff --git a/src/PJ_nsper.c b/src/PJ_nsper.c index 589b6203..4975bb17 100644 --- a/src/PJ_nsper.c +++ b/src/PJ_nsper.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -134,29 +135,12 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - static PJ *setup(PJ *P) { struct pj_opaque *Q = P->opaque; - if ((Q->height = pj_param(P->ctx, P->params, "dh").f) <= 0.) { - proj_errno_set(P, PJD_ERR_H_LESS_THAN_ZERO); - return freeup_new(P); - } + if ((Q->height = pj_param(P->ctx, P->params, "dh").f) <= 0.) + return pj_default_destructor(P, PJD_ERR_H_LESS_THAN_ZERO); + if (fabs(fabs(P->phi0) - M_HALFPI) < EPS10) Q->mode = P->phi0 < 0. ? S_POLE : N_POLE; else if (fabs(P->phi0) < EPS10) @@ -174,6 +158,7 @@ static PJ *setup(PJ *P) { P->inv = s_inverse; P->fwd = s_forward; P->es = 0.; + return P; } @@ -181,7 +166,7 @@ static PJ *setup(PJ *P) { PJ *PROJECTION(nsper) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->tilt = 0; @@ -195,7 +180,7 @@ PJ *PROJECTION(tpers) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; omega = pj_param(P->ctx, P->params, "dtilt").f * DEG_TO_RAD; diff --git a/src/PJ_nzmg.c b/src/PJ_nzmg.c index 6c705502..b489e32f 100644 --- a/src/PJ_nzmg.c +++ b/src/PJ_nzmg.c @@ -26,7 +26,7 @@ * DEALINGS IN THE SOFTWARE. *****************************************************************************/ #define PJ_LIB__ -#include <projects.h> +#include "projects.h" PROJ_HEAD(nzmg, "New Zealand Map Grid") "\n\tfixed Earth"; @@ -103,19 +103,6 @@ static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(nzmg) { /* force to International major axis */ P->ra = 1. / (P->a = 6378388.0); diff --git a/src/PJ_ob_tran.c b/src/PJ_ob_tran.c index a610a1fe..793ace38 100644 --- a/src/PJ_ob_tran.c +++ b/src/PJ_ob_tran.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" #include <string.h> @@ -80,96 +81,124 @@ static LP t_inverse(XY xy, PJ *P) { /* spheroid */ } -static void *freeup_new (PJ *P) { /* Destructor */ +static void *destructor(PJ *P, int errlev) { if (0==P) return 0; + if (0==P->opaque) - return pj_dealloc (P); + return pj_default_destructor (P, errlev); if (P->opaque->link) - { - /* This is a bit tricky: the linked PJ* shares the same params as */ - /* the current one, so unset it to avoid double free */ - /* We used to call P->opaque->link->pfree(P->opaque->link); only */ - /* but this leaked grids */ - P->opaque->link->params = NULL; - pj_free(P->opaque->link); - } + P->opaque->link->destructor (P->opaque->link, errlev); + + return pj_default_destructor(P, errlev); +} + + + + +/*********************************************************************** + +These functions are modified versions of the functions "argc_params" +and "argv_params" from PJ_pipeline.c - pj_dealloc (P->opaque); - return pj_dealloc(P); +Basically, they do the somewhat backwards stunt of turning the paralist +representation of the +args back into the original +argv, +argc +representation accepted by pj_init_ctx(). + +This, however, also begs the question of whether we really need the +paralist linked list representation, or if we could do with a simpler +null-terminated argv style array? This would simplfy some code, and +keep memory allocations more localized. + +***********************************************************************/ + +typedef struct {int argc; char **argv;} ARGS; + +/* count the number of args in the linked list <params> */ +static size_t paralist_params_argc (paralist *params) { + size_t argc = 0; + for (; params != 0; params = params->next) + argc++; + return argc; } -static void freeup (PJ *P) { - freeup_new (P); - return; +/* turn paralist into argc/argv style argument list */ +static ARGS ob_tran_target_params (paralist *params) { + int i = 0; + ARGS args = {0, 0}; + size_t argc = paralist_params_argc (params); + if (argc < 2) + return args; + + /* all args except the proj_ob_tran */ + args.argv = pj_calloc (argc - 1, sizeof (char *)); + if (0==args.argv) + return args; + + /* Copy all args *except* the proj=ob_tran arg to the argv array */ + for (i = 0; params != 0; params = params->next) { + if (0==strcmp (params->param, "proj=ob_tran")) + continue; + args.argv[i++] = params->param; + } + args.argc = i; + + /* Then convert the o_proj=xxx element to proj=xxx */ + for (i = 0; i < args.argc; i++) { + if (0!=strncmp (args.argv[i], "o_proj=", 7)) + continue; + args.argv[i] += 2; + break; + } + + return args; } + PJ *PROJECTION(ob_tran) { - int i; double phip; - char *name, *s; + char *name; + ARGS args; + PJ *R; /* projection to rotate */ struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; + if (0 != P->es) + return pj_default_destructor(P, PJD_ERR_ELLIPSOIDAL_UNSUPPORTED); + /* get name of projection to be translated */ - if (!(name = pj_param(P->ctx, P->params, "so_proj").s)) { - proj_errno_set(P, PJD_ERR_NO_ROTATION_PROJ); - return freeup_new(P); - } + if (!(name = pj_param(P->ctx, P->params, "so_proj").s)) + return destructor(P, PJD_ERR_NO_ROTATION_PROJ); + /* avoid endless recursion */ - if( strcmp(name, "ob_tran") == 0 ) { - proj_errno_set(P, PJD_ERR_FAILED_TO_FIND_PROJ); - return freeup_new(P); - } - for (i = 0; (s = pj_list[i].id) && strcmp(name, s) ; ++i) ; - if (!s || !(Q->link = (*pj_list[i].proj)(0))) { - proj_errno_set(P, PJD_ERR_FAILED_TO_FIND_PROJ); - return freeup_new(P); - } - /* copy existing header into new */ - P->es = 0.; /* force to spherical */ - Q->link->params = P->params; - Q->link->ctx = P->ctx; - Q->link->over = P->over; - Q->link->geoc = P->geoc; - Q->link->a = P->a; - Q->link->es = P->es; - Q->link->ra = P->ra; - Q->link->lam0 = P->lam0; - Q->link->phi0 = P->phi0; - Q->link->x0 = P->x0; - Q->link->y0 = P->y0; - Q->link->k0 = P->k0; - /* force spherical earth */ - Q->link->one_es = Q->link->rone_es = 1.; - Q->link->es = Q->link->e = 0.; - if (!(Q->link = pj_list[i].proj(Q->link))) { - return freeup_new(P); - } - if( Q->link->fwd == 0 ) { - return freeup_new(P); - } + if( strcmp(name, "ob_tran") == 0 ) + return destructor(P, PJD_ERR_FAILED_TO_FIND_PROJ); + + /* Create the projection object to rotate */ + args = ob_tran_target_params (P->params); + R = pj_init_ctx (pj_get_ctx(P), args.argc, args.argv); + pj_dealloc (args.argv); + + if (0==R) + return destructor (P, PJD_ERR_UNKNOWN_PROJECTION_ID); + Q->link = R; + if (pj_param(P->ctx, P->params, "to_alpha").i) { double lamc, phic, alpha; lamc = pj_param(P->ctx, P->params, "ro_lon_c").f; phic = pj_param(P->ctx, P->params, "ro_lat_c").f; alpha = pj_param(P->ctx, P->params, "ro_alpha").f; -/* - if (fabs(phic) <= TOL || - fabs(fabs(phic) - HALFPI) <= TOL || - fabs(fabs(alpha) - HALFPI) <= TOL) -*/ - if (fabs(fabs(phic) - M_HALFPI) <= TOL) { - proj_errno_set(P, PJD_ERR_LAT_0_OR_ALPHA_EQ_90); - return freeup_new(P); - } + + if (fabs(fabs(phic) - M_HALFPI) <= TOL) + return destructor(P, PJD_ERR_LAT_0_OR_ALPHA_EQ_90); + Q->lamp = lamc + aatan2(-cos(alpha), -sin(alpha) * sin(phic)); phip = aasin(P->ctx,cos(phic) * sin(alpha)); } else if (pj_param(P->ctx, P->params, "to_lat_p").i) { /* specified new pole */ @@ -183,16 +212,16 @@ PJ *PROJECTION(ob_tran) { lam2 = pj_param(P->ctx, P->params, "ro_lon_2").f; phi2 = pj_param(P->ctx, P->params, "ro_lat_2").f; if (fabs(phi1 - phi2) <= TOL || (con = fabs(phi1)) <= TOL || - fabs(con - M_HALFPI) <= TOL || fabs(fabs(phi2) - M_HALFPI) <= TOL) { - proj_errno_set(P, PJD_ERR_LAT_1_OR_2_ZERO_OR_90); - return freeup_new(P); - } + fabs(con - M_HALFPI) <= TOL || fabs(fabs(phi2) - M_HALFPI) <= TOL) + return destructor(P, PJD_ERR_LAT_1_OR_2_ZERO_OR_90); + Q->lamp = atan2(cos(phi1) * sin(phi2) * cos(lam1) - sin(phi1) * cos(phi2) * cos(lam2), sin(phi1) * cos(phi2) * sin(lam2) - cos(phi1) * sin(phi2) * sin(lam1)); phip = atan(-cos(Q->lamp - lam1) / tan(phi1)); } + if (fabs(phip) > TOL) { /* oblique */ Q->cphip = cos(phip); Q->sphip = sin(phip); @@ -213,8 +242,11 @@ int pj_ob_tran_selftest (void) {return 0;} int pj_ob_tran_selftest (void) { double tolerance_lp = 1e-10; double tolerance_xy = 1e-7; + double d; + PJ *P; + PJ_COORD a, b; - char s_args[] = {"+proj=ob_tran +a=6400000 +o_proj=latlon +o_lon_p=20 +o_lat_p=20 +lon_0=180"}; + char s_args[] = {"+proj=ob_tran +R=6400000 +o_proj=latlon +o_lon_p=20 +o_lat_p=20 +lon_0=180"}; LP fwd_in[] = { { 2, 1}, @@ -244,7 +276,31 @@ int pj_ob_tran_selftest (void) { {-65.862385598848391, 51.830295078417215}, }; + /* -- Tests from nad/testvarious -------------------------------------------- */ + P = proj_create (0, "+proj=ob_tran +o_proj=moll +a=6378137.0 +es=0 +o_lon_p=0 +o_lat_p=0 +lon_0=180"); + if (0==P) + return 1; + + a = proj_coord (300000, 400000, 0, 0); + b.lpz.lam = -proj_torad (42 + (45 + 22.377/60)/60); + b.lpz.phi = proj_torad (85 + (35 + 28.083/60)/60); + a = proj_trans_coord (P, -1, a); + d = proj_lp_dist (P, a.lp, b.lp); + if (d > 1e-3) + return 2; + + a = proj_coord (proj_torad(10), proj_torad(20), 0, 0); + b = proj_coord (-1384841.18787, 7581707.88240, 0, 0); + a = proj_trans_coord (P, 1, a); + d = proj_xy_dist (a.xy, b.xy); + if (d > 1e-3) + return 3; + + proj_destroy (P); + /* -------------------------------------------------------------------------- */ + + return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); } -#endif +#endif
\ No newline at end of file diff --git a/src/PJ_ocea.c b/src/PJ_ocea.c index 1fbe2768..d3fe9fe7 100644 --- a/src/PJ_ocea.c +++ b/src/PJ_ocea.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <projects.h> PROJ_HEAD(ocea, "Oblique Cylindrical Equal Area") "\n\tCyl, Sph" @@ -44,28 +45,12 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(ocea) { double phi_0=0.0, phi_1, phi_2, lam_1, lam_2, lonz, alpha; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->rok = 1. / P->k0; diff --git a/src/PJ_oea.c b/src/PJ_oea.c index 2ba7917f..800a266e 100644 --- a/src/PJ_oea.c +++ b/src/PJ_oea.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -52,32 +53,17 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} PJ *PROJECTION(oea) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; if (((Q->n = pj_param(P->ctx, P->params, "dn").f) <= 0.) || ((Q->m = pj_param(P->ctx, P->params, "dm").f) <= 0.)) { - proj_errno_set(P, PJD_ERR_INVALID_M_OR_N); - return freeup_new(P); + return pj_default_destructor(P, PJD_ERR_INVALID_M_OR_N); } else { Q->theta = pj_param(P->ctx, P->params, "rtheta").f; Q->sp0 = sin(P->phi0); diff --git a/src/PJ_omerc.c b/src/PJ_omerc.c index 0d86e460..f0b4b439 100644 --- a/src/PJ_omerc.c +++ b/src/PJ_omerc.c @@ -22,6 +22,7 @@ ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -111,22 +112,6 @@ static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(omerc) { double con, com, cosph0, D, F, H, L, sinph0, p, J, gamma=0, gamma0, lamc=0, lam1=0, lam2=0, phi1=0, phi2=0, alpha_c=0; @@ -134,7 +119,7 @@ PJ *PROJECTION(omerc) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->no_rot = pj_param(P->ctx, P->params, "tno_rot").i; @@ -164,10 +149,8 @@ PJ *PROJECTION(omerc) { (con = fabs(phi1)) <= TOL || fabs(con - M_HALFPI) <= TOL || fabs(fabs(P->phi0) - M_HALFPI) <= TOL || - fabs(fabs(phi2) - M_HALFPI) <= TOL) { - proj_errno_set(P, PJD_ERR_LAT_0_OR_ALPHA_EQ_90); - return freeup_new(P); - } + fabs(fabs(phi2) - M_HALFPI) <= TOL) + return pj_default_destructor(P, PJD_ERR_LAT_0_OR_ALPHA_EQ_90); } com = sqrt(P->one_es); if (fabs(P->phi0) > EPS) { diff --git a/src/PJ_ortho.c b/src/PJ_ortho.c index bb150f05..3179189b 100644 --- a/src/PJ_ortho.c +++ b/src/PJ_ortho.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -104,26 +105,11 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - PJ *PROJECTION(ortho) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; if (fabs(fabs(P->phi0) - M_HALFPI) <= EPS10) diff --git a/src/PJ_patterson.c b/src/PJ_patterson.c index 952b63ea..40b90010 100644 --- a/src/PJ_patterson.c +++ b/src/PJ_patterson.c @@ -105,19 +105,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(patterson) { P->es = 0.; P->inv = s_inverse; diff --git a/src/PJ_pipeline.c b/src/PJ_pipeline.c index a26f3ccf..9352b4fd 100644 --- a/src/PJ_pipeline.c +++ b/src/PJ_pipeline.c @@ -260,29 +260,17 @@ static LP pipeline_reverse (XY xy, PJ *P) { return point.coo.lp; } -static void freeup(PJ *P) { /* Destructor */ - if (P==0) - return; - /* Projection specific deallocation goes here */ - pj_dealloc (P->opaque); - pj_dealloc (P); - return; -} - -static void *pipeline_freeup (PJ *P, int errlev) { /* Destructor */ +static void *destructor (PJ *P, int errlev) { int i; if (0==P) return 0; - if (errlev) - proj_errno_set (P, errlev); - if (0==P->opaque) - return pj_dealloc (P); + return pj_default_destructor (P, errlev); for (i = 0; i < P->opaque->steps; i++) - pj_free (P->opaque->pipeline[i+1]); + pj_default_destructor (P->opaque->pipeline[i+1], errlev); pj_dealloc (P->opaque->reverse_step); pj_dealloc (P->opaque->omit_forward); @@ -291,15 +279,7 @@ static void *pipeline_freeup (PJ *P, int errlev) { /* Destructor */ pj_dealloc (P->opaque->current_argv); pj_dealloc (P->opaque->pipeline); - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -/* Adapts pipeline_freeup to the format defined for the PJ object */ -static void pipeline_freeup_wrapper (PJ *P) { - pipeline_freeup (P, 0); - return; + return pj_default_destructor(P, errlev); } @@ -364,27 +344,27 @@ PJ *PROJECTION(pipeline) { P->inv3d = pipeline_reverse_3d; P->fwd = pipeline_forward; P->inv = pipeline_reverse; - P->pfree = pipeline_freeup_wrapper; + P->destructor = destructor; P->opaque = pj_calloc (1, sizeof(struct pj_opaque)); if (0==P->opaque) - return 0; + return pj_default_destructor(P, ENOMEM); argc = (int)argc_params (P->params); P->opaque->argv = argv = argv_params (P->params, argc); if (0==argv) - return pipeline_freeup (P, ENOMEM); + return destructor (P, ENOMEM); P->opaque->current_argv = current_argv = pj_calloc (argc, sizeof (char *)); if (0==current_argv) - return pipeline_freeup (P, ENOMEM); + return destructor (P, ENOMEM); /* Do some syntactical sanity checking */ for (i = 0; i < argc; i++) { if (0==strcmp ("step", argv[i])) { if (-1==i_pipeline) { proj_log_error (P, "Pipeline: +step before +proj=pipeline"); - return pipeline_freeup (P, -50); + return destructor (P, PJD_ERR_MALFORMED_PIPELINE); } if (0==nsteps) i_first_step = i; @@ -395,7 +375,7 @@ PJ *PROJECTION(pipeline) { if (0==strcmp ("proj=pipeline", argv[i])) { if (-1 != i_pipeline) { proj_log_error (P, "Pipeline: Nesting invalid"); - return pipeline_freeup (P, -50); /* ERROR: nested pipelines */ + return destructor (P, PJD_ERR_MALFORMED_PIPELINE); /* ERROR: nested pipelines */ } i_pipeline = i; } @@ -404,14 +384,14 @@ PJ *PROJECTION(pipeline) { P->opaque->steps = nsteps; if (-1==i_pipeline) - return pipeline_freeup (P, -50); /* ERROR: no pipeline def */ + return destructor (P, PJD_ERR_MALFORMED_PIPELINE); /* ERROR: no pipeline def */ if (0==nsteps) - return pipeline_freeup (P, -50); /* ERROR: no pipeline def */ + return destructor (P, PJD_ERR_MALFORMED_PIPELINE); /* ERROR: no pipeline def */ /* Make room for the pipeline and execution indicators */ if (0==pj_create_pipeline (P, nsteps)) - return pipeline_freeup (P, ENOMEM); + return destructor (P, ENOMEM); /* Now loop over all steps, building a new set of arguments for each init */ for (i_current_step = i_first_step, i = 0; i < nsteps; i++) { @@ -454,7 +434,7 @@ PJ *PROJECTION(pipeline) { proj_log_trace (P, "Pipeline: Step %d at %p", i, next_step); if (0==next_step) { proj_log_error (P, "Pipeline: Bad step definition: %s", current_argv[0]); - return pipeline_freeup (P, -50); /* ERROR: bad pipeline def */ + return destructor (P, PJD_ERR_MALFORMED_PIPELINE); /* ERROR: bad pipeline def */ } P->opaque->pipeline[i+1] = next_step; proj_log_trace (P, "Pipeline: step done"); @@ -470,7 +450,7 @@ PJ *PROJECTION(pipeline) { break; if (i==nsteps) { proj_log_error (P, "Pipeline: No forward steps"); - return pipeline_freeup (P, -50); + return destructor (P, PJD_ERR_MALFORMED_PIPELINE); } if (P->opaque->reverse_step[i + 1]) @@ -493,7 +473,7 @@ PJ *PROJECTION(pipeline) { break; if (i==-1) { proj_log_error (P, "Pipeline: No reverse steps"); - return pipeline_freeup (P, -50); + return destructor (P, PJD_ERR_MALFORMED_PIPELINE); } if (P->opaque->reverse_step[i + 1]) diff --git a/src/PJ_poly.c b/src/PJ_poly.c index f5af36ac..209669c0 100644 --- a/src/PJ_poly.c +++ b/src/PJ_poly.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -126,32 +127,31 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ +static void *destructor(PJ *P, int errlev) { if (0==P) return 0; + if (0==P->opaque) - return pj_dealloc (P); + return pj_default_destructor (P, errlev); + if (P->opaque->en) pj_dealloc (P->opaque->en); - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; + return pj_default_destructor(P, errlev); } PJ *PROJECTION(poly) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); + P->opaque = Q; + P->destructor = destructor; if (P->es != 0.0) { - if (!(Q->en = pj_enfn(P->es))) return freeup_new(P); + if (!(Q->en = pj_enfn(P->es))) + return pj_default_destructor (P, ENOMEM); Q->ml0 = pj_mlfn(P->phi0, sin(P->phi0), cos(P->phi0), Q->en); P->inv = e_inverse; P->fwd = e_forward; diff --git a/src/PJ_putp2.c b/src/PJ_putp2.c index 052d95bb..83aa5f45 100644 --- a/src/PJ_putp2.c +++ b/src/PJ_putp2.c @@ -49,19 +49,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(putp2) { P->es = 0.; P->inv = s_inverse; diff --git a/src/PJ_putp3.c b/src/PJ_putp3.c index 93720915..cb216370 100644 --- a/src/PJ_putp3.c +++ b/src/PJ_putp3.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <projects.h> struct pj_opaque { @@ -32,27 +33,10 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(putp3) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->A = 4. * RPISQ; @@ -67,7 +51,7 @@ PJ *PROJECTION(putp3) { PJ *PROJECTION(putp3p) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->A = 2. * RPISQ; diff --git a/src/PJ_putp4p.c b/src/PJ_putp4p.c index f8b65cee..197f24c4 100644 --- a/src/PJ_putp4p.c +++ b/src/PJ_putp4p.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <projects.h> struct pj_opaque { @@ -36,27 +37,10 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(putp4p) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->C_x = 0.874038744; @@ -73,7 +57,7 @@ PJ *PROJECTION(putp4p) { PJ *PROJECTION(weren) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->C_x = 1.; diff --git a/src/PJ_putp5.c b/src/PJ_putp5.c index 87b7af74..f8b431b1 100644 --- a/src/PJ_putp5.c +++ b/src/PJ_putp5.c @@ -1,5 +1,6 @@ #define PJ_LIB__ -#include <projects.h> +#include <errno.h> +#include "projects.h" struct pj_opaque { double A, B; @@ -34,27 +35,11 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - PJ *PROJECTION(putp5) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->A = 2.; @@ -71,7 +56,7 @@ PJ *PROJECTION(putp5) { PJ *PROJECTION(putp5p) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->A = 1.5; diff --git a/src/PJ_putp6.c b/src/PJ_putp6.c index 6c4fc246..50859f14 100644 --- a/src/PJ_putp6.c +++ b/src/PJ_putp6.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <projects.h> struct pj_opaque { @@ -51,27 +52,10 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(putp6) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; Q->C_x = 1.01346; @@ -91,7 +75,7 @@ PJ *PROJECTION(putp6) { PJ *PROJECTION(putp6p) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; Q->C_x = 0.44329; diff --git a/src/PJ_qsc.c b/src/PJ_qsc.c index e5fee0ea..f8c760a9 100644 --- a/src/PJ_qsc.c +++ b/src/PJ_qsc.c @@ -39,7 +39,8 @@ */ #define PJ_LIB__ -#include <projects.h> +#include <errno.h> +#include "projects.h" struct pj_opaque { int face; @@ -361,27 +362,10 @@ static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(qsc) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; P->inv = e_inverse; diff --git a/src/PJ_robin.c b/src/PJ_robin.c index 60a52324..d3f92cd9 100644 --- a/src/PJ_robin.c +++ b/src/PJ_robin.c @@ -145,20 +145,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(robin) { P->es = 0.; P->inv = s_inverse; diff --git a/src/PJ_rpoly.c b/src/PJ_rpoly.c index d0ff8319..8f7b16c6 100644 --- a/src/PJ_rpoly.c +++ b/src/PJ_rpoly.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <projects.h> struct pj_opaque { @@ -34,27 +35,11 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - PJ *PROJECTION(rpoly) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; if ((Q->mode = (Q->phi1 = fabs(pj_param(P->ctx, P->params, "rlat_ts").f)) > EPS)) { diff --git a/src/PJ_sch.c b/src/PJ_sch.c index 6c97a4f3..dc8cc770 100644 --- a/src/PJ_sch.c +++ b/src/PJ_sch.c @@ -33,6 +33,7 @@ ****************************************************************************/ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" #include "geocent.h" @@ -86,11 +87,6 @@ static LPZ inverse3d(XYZ xyz, PJ *P) { lpz.phi = temp[0] ; lpz.z = temp[2]; -#if 0 - printf("INVERSE: \n"); - printf("XYZ: %f %f %f \n", xyz.x, xyz.y, xyz.z); - printf("LPZ: %f %f %f \n", lpz.lam, lpz.phi, lpz.z); -#endif return lpz; } @@ -129,30 +125,10 @@ static XYZ forward3d(LPZ lpz, PJ *P) { xyz.y = temp[0] * Q->rcurv / P->a; xyz.z = temp[2]; -#if 0 - printf("FORWARD: \n"); - printf("LPZ: %f %f %f \n", lpz.lam, lpz.phi, lpz.z); - printf("XYZ: %f %f %f \n", xyz.x, xyz.y, xyz.z); -#endif return xyz; } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - static PJ *setup(PJ *P) { /* general initialization */ struct pj_opaque *Q = P->opaque; double reast, rnorth; @@ -165,10 +141,8 @@ static PJ *setup(PJ *P) { /* general initialization */ temp = P->a * sqrt(1.0 - P->es); /* Setup original geocentric system */ - if ( pj_Set_Geocentric_Parameters(&(Q->elp_0), P->a, temp) != 0) { - proj_errno_set(P, PJD_ERR_FAILED_TO_FIND_PROJ); - return freeup_new(P); - } + if ( pj_Set_Geocentric_Parameters(&(Q->elp_0), P->a, temp) != 0) + return pj_default_destructor(P, PJD_ERR_FAILED_TO_FIND_PROJ); clt = cos(Q->plat); slt = sin(Q->plat); @@ -185,17 +159,10 @@ static PJ *setup(PJ *P) { /* general initialization */ Q->rcurv = Q->h0 + (reast*rnorth)/(reast * chdg * chdg + rnorth * shdg * shdg); -#if 0 - printf("North Radius: %f \n", rnorth); - printf("East Radius: %f \n", reast); - printf("Effective Radius: %f \n", Q->rcurv); -#endif - /* Set up local sphere at the given peg point */ - if ( pj_Set_Geocentric_Parameters(&(Q->sph), Q->rcurv, Q->rcurv) != 0) { - proj_errno_set(P, PJD_ERR_FAILED_TO_FIND_PROJ); - return freeup_new(P); - } + if ( pj_Set_Geocentric_Parameters(&(Q->sph), Q->rcurv, Q->rcurv) != 0) + return pj_default_destructor(P, PJD_ERR_FAILED_TO_FIND_PROJ); + /* Set up the transformation matrices */ Q->transMat[0] = clt * clo; Q->transMat[1] = -shdg*slo - slt*clo * chdg; @@ -210,20 +177,13 @@ static PJ *setup(PJ *P) { /* general initialization */ if( pj_Convert_Geodetic_To_Geocentric( &(Q->elp_0), Q->plat, Q->plon, Q->h0, pxyz, pxyz+1, pxyz+2 ) != 0 ) - { - proj_errno_set(P, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT); - return freeup_new(P); - } + return pj_default_destructor(P, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT); Q->xyzoff[0] = pxyz[0] - (Q->rcurv) * clt * clo; Q->xyzoff[1] = pxyz[1] - (Q->rcurv) * clt * slo; Q->xyzoff[2] = pxyz[2] - (Q->rcurv) * slt; -#if 0 - printf("Offset: %f %f %f \n", Q->xyzoff[0], Q->xyzoff[1], Q->xyzoff[2]); -#endif - P->fwd3d = forward3d; P->inv3d = inverse3d; return P; @@ -233,7 +193,7 @@ static PJ *setup(PJ *P) { /* general initialization */ PJ *PROJECTION(sch) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; Q->h0 = 0.0; @@ -242,24 +202,21 @@ PJ *PROJECTION(sch) { if (pj_param(P->ctx, P->params, "tplat_0").i) Q->plat = pj_param(P->ctx, P->params, "rplat_0").f; else { - proj_errno_set(P, PJD_ERR_FAILED_TO_FIND_PROJ); - return freeup_new(P); + return pj_default_destructor(P, PJD_ERR_FAILED_TO_FIND_PROJ); } /* Check if peg longitude was defined */ if (pj_param(P->ctx, P->params, "tplon_0").i) Q->plon = pj_param(P->ctx, P->params, "rplon_0").f; else { - proj_errno_set(P, PJD_ERR_FAILED_TO_FIND_PROJ); - return freeup_new(P); + return pj_default_destructor(P, PJD_ERR_FAILED_TO_FIND_PROJ); } /* Check if peg latitude is defined */ if (pj_param(P->ctx, P->params, "tphdg_0").i) Q->phdg = pj_param(P->ctx, P->params, "rphdg_0").f; else { - proj_errno_set(P, PJD_ERR_FAILED_TO_FIND_PROJ); - return freeup_new(P); + return pj_default_destructor(P, PJD_ERR_FAILED_TO_FIND_PROJ); } @@ -267,10 +224,6 @@ PJ *PROJECTION(sch) { if (pj_param(P->ctx, P->params, "th_0").i) Q->h0 = pj_param(P->ctx, P->params, "dh_0").f; - /* Completed reading in the projection parameters */ -#if 0 - printf("PSA: Lat = %f Lon = %f Hdg = %f \n", Q->plat, Q->plon, Q->phdg); -#endif return setup(P); } diff --git a/src/PJ_sconics.c b/src/PJ_sconics.c index 8759c66e..7f6e094c 100644 --- a/src/PJ_sconics.c +++ b/src/PJ_sconics.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -105,35 +106,19 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, (and ellipsoidal?) inverse } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - static PJ *setup(PJ *P, int type) { double del, cs; - int i; + int err; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->type = type; - i = phi12 (P, &del); - if(i) { - proj_errno_set(P, i); - return freeup_new(P); - } + err = phi12 (P, &del); + if(err) + return pj_default_destructor (P, err); + switch (Q->type) { case TISSOT: @@ -172,10 +157,9 @@ static PJ *setup(PJ *P, int type) { Q->n = sin (Q->sig); Q->c2 = cos (del); Q->c1 = 1./tan (Q->sig); - if (fabs (del = P->phi0 - Q->sig) - EPS10 >= M_HALFPI) { - proj_errno_set(P, PJD_ERR_LAT_0_HALF_PI_FROM_MEAN); - return freeup_new(P); - } + if (fabs (del = P->phi0 - Q->sig) - EPS10 >= M_HALFPI) + return pj_default_destructor(P, PJD_ERR_LAT_0_HALF_PI_FROM_MEAN); + Q->rho_0 = Q->c2 * (Q->c1 - tan (del)); break; diff --git a/src/PJ_somerc.c b/src/PJ_somerc.c index 751d0c77..7324d48a 100644 --- a/src/PJ_somerc.c +++ b/src/PJ_somerc.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -63,31 +64,11 @@ static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -#if 0 -FREEUP; if (P) pj_dalloc(P); } -#endif - - -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(somerc) { double cp, phip0, sp; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/PJ_stere.c b/src/PJ_stere.c index befca308..02b73507 100644 --- a/src/PJ_stere.c +++ b/src/PJ_stere.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -213,19 +214,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - static PJ *setup(PJ *P) { /* general initialization */ double t; struct pj_opaque *Q = P->opaque; @@ -291,7 +279,7 @@ static PJ *setup(PJ *P) { /* general initialization */ PJ *PROJECTION(stere) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->phits = pj_param (P->ctx, P->params, "tlat_ts").i ? @@ -304,14 +292,14 @@ PJ *PROJECTION(stere) { PJ *PROJECTION(ups) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; /* International Ellipsoid */ P->phi0 = pj_param(P->ctx, P->params, "bsouth").i ? - M_HALFPI: M_HALFPI; if (P->es == 0.0) { proj_errno_set(P, PJD_ERR_ELLIPSOID_USE_REQUIRED); - return freeup_new(P); + return pj_default_destructor (P, ENOMEM); } P->k0 = .994; P->x0 = 2000000.; diff --git a/src/PJ_sterea.c b/src/PJ_sterea.c index 73c6b48c..e0ff15e7 100644 --- a/src/PJ_sterea.c +++ b/src/PJ_sterea.c @@ -24,7 +24,8 @@ ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define PJ_LIB__ -#include <projects.h> +#include <errno.h> +#include <projects.h> struct pj_opaque { @@ -78,21 +79,15 @@ static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ +static void *destructor (PJ *P, int errlev) { if (0==P) return 0; + if (0==P->opaque) - return pj_dealloc (P); + return pj_default_destructor (P, errlev); pj_dealloc (P->opaque->en); - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; + return pj_default_destructor (P, errlev); } @@ -101,12 +96,12 @@ PJ *PROJECTION(sterea) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->en = pj_gauss_ini(P->e, P->phi0, &(Q->phic0), &R); if (0==Q->en) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); Q->sinc0 = sin (Q->phic0); Q->cosc0 = cos (Q->phic0); @@ -114,6 +109,8 @@ PJ *PROJECTION(sterea) { P->inv = e_inverse; P->fwd = e_forward; + P->destructor = destructor; + return P; } diff --git a/src/PJ_sts.c b/src/PJ_sts.c index b6b6dc43..3e6168bd 100644 --- a/src/PJ_sts.c +++ b/src/PJ_sts.c @@ -1,5 +1,6 @@ #define PJ_LIB__ -# include <projects.h> +#include <errno.h> +#include "projects.h" PROJ_HEAD(kav5, "Kavraisky V") "\n\tPCyl., Sph."; PROJ_HEAD(qua_aut, "Quartic Authalic") "\n\tPCyl., Sph."; @@ -8,7 +9,7 @@ PROJ_HEAD(mbt_s, "McBryde-Thomas Flat-Polar Sine (No. 1)") "\n\tPCyl., Sph."; struct pj_opaque { - double C_x, C_y, C_p; \ + double C_x, C_y, C_p; int tan_mode; }; @@ -50,19 +51,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - static PJ *setup(PJ *P, double p, double q, int mode) { P->es = 0.; P->inv = s_inverse; @@ -81,7 +69,7 @@ static PJ *setup(PJ *P, double p, double q, int mode) { PJ *PROJECTION(fouc) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; return setup(P, 2., 2., 1); } @@ -151,7 +139,7 @@ int pj_fouc_selftest (void) { PJ *PROJECTION(kav5) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; return setup(P, 1.50488, 1.35439, 0); @@ -221,7 +209,7 @@ int pj_kav5_selftest (void) { PJ *PROJECTION(qua_aut) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; return setup(P, 2., 2., 0); } @@ -289,7 +277,7 @@ int pj_qua_aut_selftest (void) { PJ *PROJECTION(mbt_s) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; return setup(P, 1.48875, 1.36509, 0); } diff --git a/src/PJ_tcc.c b/src/PJ_tcc.c index 80bb6bc8..26cf67b6 100644 --- a/src/PJ_tcc.c +++ b/src/PJ_tcc.c @@ -22,16 +22,6 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ } -static void *freeup_new (PJ *P) { /* Destructor */ - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(tcc) { P->es = 0.; P->fwd = s_forward; diff --git a/src/PJ_tcea.c b/src/PJ_tcea.c index d219928d..65b3c604 100644 --- a/src/PJ_tcea.c +++ b/src/PJ_tcea.c @@ -25,16 +25,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(tcea) { P->inv = s_inverse; P->fwd = s_forward; diff --git a/src/PJ_times.c b/src/PJ_times.c index 5d3b0391..a8d6e67a 100644 --- a/src/PJ_times.c +++ b/src/PJ_times.c @@ -66,20 +66,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(times) { P->es = 0.0; diff --git a/src/PJ_tmerc.c b/src/PJ_tmerc.c index 04afc64c..b3ec0030 100644 --- a/src/PJ_tmerc.c +++ b/src/PJ_tmerc.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -160,26 +161,24 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ +static void *destructor(PJ *P, int errlev) { /* Destructor */ if (0==P) return 0; + if (0==P->opaque) - return pj_dealloc (P); + return pj_default_destructor(P, errlev); + pj_dealloc (P->opaque->en); - pj_dealloc (P->opaque); - return pj_dealloc(P); + return pj_default_destructor(P, errlev); } -static void freeup (PJ *P) { - freeup_new (P); - return; -} static PJ *setup(PJ *P) { /* general initialization */ struct pj_opaque *Q = P->opaque; if (P->es != 0.0) { if (!(Q->en = pj_enfn(P->es))) - return freeup_new(P); + return pj_default_destructor(P, ENOMEM); + Q->ml0 = pj_mlfn(P->phi0, sin(P->phi0), cos(P->phi0), Q->en); Q->esp = P->es / (1. - P->es); P->inv = e_inverse; @@ -197,8 +196,11 @@ static PJ *setup(PJ *P) { /* general initialization */ PJ *PROJECTION(tmerc) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); + P->opaque = Q; + P->destructor = destructor; + return setup(P); } diff --git a/src/PJ_tpeqd.c b/src/PJ_tpeqd.c index 90dd7568..6bea3968 100644 --- a/src/PJ_tpeqd.c +++ b/src/PJ_tpeqd.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -7,7 +8,7 @@ PROJ_HEAD(tpeqd, "Two Point Equidistant") "\n\tMisc Sph\n\tlat_1= lon_1= lat_2= lon_2="; struct pj_opaque { - double cp1, sp1, cp2, sp2, ccs, cs, sc, r2z0, z02, dlam2; \ + double cp1, sp1, cp2, sp2, ccs, cs, sc, r2z0, z02, dlam2; double hz0, thz0, rhshz0, ca, sa, lp, lamc; }; @@ -55,26 +56,11 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(tpeqd) { double lam_1, lam_2, phi_1, phi_2, A12, pp; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; @@ -84,10 +70,9 @@ PJ *PROJECTION(tpeqd) { phi_2 = pj_param(P->ctx, P->params, "rlat_2").f; lam_2 = pj_param(P->ctx, P->params, "rlon_2").f; - if (phi_1 == phi_2 && lam_1 == lam_2) { - proj_errno_set(P, PJD_ERR_CONTROL_POINT_NO_DIST); - return freeup_new(P); - } + if (phi_1 == phi_2 && lam_1 == lam_2) + return pj_default_destructor(P, PJD_ERR_CONTROL_POINT_NO_DIST); + P->lam0 = adjlon (0.5 * (lam_1 + lam_2)); Q->dlam2 = adjlon (lam_2 - lam_1); diff --git a/src/PJ_unitconvert.c b/src/PJ_unitconvert.c index 7ce6035c..62a9c1d1 100644 --- a/src/PJ_unitconvert.c +++ b/src/PJ_unitconvert.c @@ -65,9 +65,9 @@ Last update: 2017-05-16 #define PJ_LIB__ #include <time.h> -#include "proj_internal.h" -#include <projects.h> #include <errno.h> +#include "proj_internal.h" +#include "projects.h" PROJ_HEAD(unitconvert, "Unit conversion"); @@ -192,28 +192,6 @@ struct pj_opaque_unitconvert { /***********************************************************************/ -static void *freeup_msg (PJ *P, int errlev) { -/***********************************************************************/ - if (0==P) - return 0; - - if (0!=P->ctx) - pj_ctx_set_errno (P->ctx, errlev); - - pj_dealloc (P->opaque); - - return pj_dealloc(P); -} - - -/***********************************************************************/ -static void freeup (PJ *P) { -/***********************************************************************/ - freeup_msg (P, 0); - return; -} - -/***********************************************************************/ static XY forward_2d(LP lp, PJ *P) { /************************************************************************ Forward unit conversions in the plane @@ -328,7 +306,7 @@ PJ *PROJECTION(unitconvert) { int i; if (0==Q) - return freeup_msg (P, ENOMEM); + return pj_default_destructor (P, ENOMEM); P->opaque = (void *) Q; P->fwdobs = forward_obs; @@ -348,7 +326,7 @@ PJ *PROJECTION(unitconvert) { if ((name = pj_param (P->ctx, P->params, "sxy_in").s) != NULL) { for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i); - if (!s) return freeup_msg(P, -8); /* unknown unit conversion id */ + if (!s) return pj_default_destructor(P, PJD_ERR_UNKNOW_UNIT_ID); Q->xy_in_id = i; proj_log_debug(P, "xy_in unit: %s", pj_units[i].name); @@ -357,7 +335,7 @@ PJ *PROJECTION(unitconvert) { if ((name = pj_param (P->ctx, P->params, "sxy_out").s) != NULL) { for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i); - if (!s) return freeup_msg(P, -8); /* unknown unit conversion id */ + if (!s) return pj_default_destructor(P, PJD_ERR_UNKNOW_UNIT_ID); Q->xy_out_id = i; proj_log_debug(P, "xy_out unit: %s", pj_units[i].name); @@ -366,7 +344,7 @@ PJ *PROJECTION(unitconvert) { if ((name = pj_param (P->ctx, P->params, "sz_in").s) != NULL) { for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i); - if (!s) return freeup_msg(P, -8); /* unknown unit conversion id */ + if (!s) return pj_default_destructor(P, PJD_ERR_UNKNOW_UNIT_ID); /* unknown unit conversion id */ Q->z_in_id = i; proj_log_debug(P, "z_in unit: %s", pj_units[i].name); @@ -375,7 +353,7 @@ PJ *PROJECTION(unitconvert) { if ((name = pj_param (P->ctx, P->params, "sz_out").s) != NULL) { for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i); - if (!s) return freeup_msg(P, -8); /* unknown unit conversion id */ + if (!s) return pj_default_destructor(P, PJD_ERR_UNKNOW_UNIT_ID); /* unknown unit conversion id */ Q->z_out_id = i; proj_log_debug(P, "z_out unit: %s", pj_units[i].name); @@ -385,7 +363,7 @@ PJ *PROJECTION(unitconvert) { if ((name = pj_param (P->ctx, P->params, "st_in").s) != NULL) { for (i = 0; (s = time_units[i].id) && strcmp(name, s) ; ++i); - if (!s) return freeup_msg(P, -8); /* unknown unit conversion id */ + if (!s) return pj_default_destructor(P, PJD_ERR_UNKNOW_UNIT_ID); /* unknown unit conversion id */ Q->t_in_id = i; proj_log_debug(P, "t_in unit: %s", time_units[i].name); @@ -394,9 +372,9 @@ PJ *PROJECTION(unitconvert) { s = 0; if ((name = pj_param (P->ctx, P->params, "st_out").s) != NULL) { for (i = 0; (s = time_units[i].id) && strcmp(name, s) ; ++i); - if (!s) { - return freeup_msg(P, -8); /* unknown unit conversion id */ - } + + if (!s) return pj_default_destructor(P, PJD_ERR_UNKNOW_UNIT_ID); /* unknown unit conversion id */ + Q->t_out_id = i; proj_log_debug(P, "t_out unit: %s", time_units[i].name); } diff --git a/src/PJ_urm5.c b/src/PJ_urm5.c index 4edb4215..bd073459 100644 --- a/src/PJ_urm5.c +++ b/src/PJ_urm5.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -22,36 +23,19 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (P->opaque) - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(urm5) { double alpha, t; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; if (pj_param(P->ctx, P->params, "tn").i) { Q->n = pj_param(P->ctx, P->params, "dn").f; - if (Q->n <= 0. || Q->n > 1.) { - proj_errno_set(P, PJD_ERR_N_OUT_OF_RANGE); - return freeup_new(P); - } + if (Q->n <= 0. || Q->n > 1.) + return pj_default_destructor(P, PJD_ERR_N_OUT_OF_RANGE); } else { - proj_errno_set(P, PJD_ERR_N_OUT_OF_RANGE); - return freeup_new(P); + return pj_default_destructor(P, PJD_ERR_N_OUT_OF_RANGE); } Q->q3 = pj_param(P->ctx, P->params, "dq").f / 3.; alpha = pj_param(P->ctx, P->params, "ralpha").f; diff --git a/src/PJ_urmfps.c b/src/PJ_urmfps.c index fcc7b853..64eb5c80 100644 --- a/src/PJ_urmfps.c +++ b/src/PJ_urmfps.c @@ -1,4 +1,5 @@ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -31,20 +32,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - static PJ *setup(PJ *P) { P->opaque->C_y = Cy / P->opaque->n; P->es = 0.; @@ -57,18 +44,16 @@ static PJ *setup(PJ *P) { PJ *PROJECTION(urmfps) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); + P->opaque = Q; if (pj_param(P->ctx, P->params, "tn").i) { P->opaque->n = pj_param(P->ctx, P->params, "dn").f; - if (P->opaque->n <= 0. || P->opaque->n > 1.) { - proj_errno_set(P, PJD_ERR_N_OUT_OF_RANGE); - return freeup_new(P); - } + if (P->opaque->n <= 0. || P->opaque->n > 1.) + return pj_default_destructor(P, PJD_ERR_N_OUT_OF_RANGE); } else { - proj_errno_set(P, PJD_ERR_N_OUT_OF_RANGE); - return freeup_new(P); + return pj_default_destructor(P, PJD_ERR_N_OUT_OF_RANGE); } return setup(P); @@ -78,7 +63,7 @@ PJ *PROJECTION(urmfps) { PJ *PROJECTION(wag1) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; P->opaque->n = 0.8660254037844386467637231707; diff --git a/src/PJ_vandg.c b/src/PJ_vandg.c index 282eb661..e19d01b8 100644 --- a/src/PJ_vandg.c +++ b/src/PJ_vandg.c @@ -97,20 +97,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(vandg) { P->es = 0.; P->inv = s_inverse; diff --git a/src/PJ_vandg2.c b/src/PJ_vandg2.c index fac7e85d..3f11e289 100644 --- a/src/PJ_vandg2.c +++ b/src/PJ_vandg2.c @@ -1,5 +1,6 @@ #define PJ_LIB__ -#include <projects.h> +#include <errno.h> +#include "projects.h" struct pj_opaque { int vdg3; @@ -44,27 +45,10 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(vandg2) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->vdg3 = 0; @@ -76,7 +60,7 @@ PJ *PROJECTION(vandg2) { PJ *PROJECTION(vandg3) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; Q->vdg3 = 1; diff --git a/src/PJ_vandg4.c b/src/PJ_vandg4.c index 2dbb0713..f7f48b43 100644 --- a/src/PJ_vandg4.c +++ b/src/PJ_vandg4.c @@ -44,20 +44,6 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(vandg4) { P->es = 0.; P->fwd = s_forward; diff --git a/src/PJ_vgridshift.c b/src/PJ_vgridshift.c index 0f031d4f..d58972f4 100644 --- a/src/PJ_vgridshift.c +++ b/src/PJ_vgridshift.c @@ -1,25 +1,9 @@ #define PJ_LIB__ #include "proj_internal.h" -#include <projects.h> +#include "projects.h" PROJ_HEAD(vgridshift, "Vertical grid shift"); -static void *freeup_msg (PJ *P, int errlev) { - if (0==P) - return 0; - - if (0!=P->ctx) - pj_ctx_set_errno (P->ctx, errlev); - - return pj_dealloc(P); -} - - -static void freeup (PJ *P) { - freeup_msg (P, 0); - return; -} - static XYZ forward_3d(LPZ lpz, PJ *P) { PJ_TRIPLET point; @@ -74,7 +58,7 @@ PJ *PROJECTION(vgridshift) { if (!pj_param(P->ctx, P->params, "tgrids").i) { proj_log_error(P, "vgridshift: +grids parameter missing."); - return freeup_msg(P, -1); + return pj_default_destructor(P, PJD_ERR_NO_ARGS); } /* Build gridlist. P->gridlist can be empty if +grids only ask for optional grids. */ @@ -84,9 +68,7 @@ PJ *PROJECTION(vgridshift) { /* Was gridlist compiled properly? */ if ( pj_ctx_get_errno(P->ctx) ) { proj_log_error(P, "vgridshift: could not find required grid(s)."); - pj_dalloc(P->gridlist); - P->gridlist = NULL; - return freeup_msg(P, -38); + return pj_default_destructor(P, -38); } P->fwdobs = forward_obs; @@ -111,16 +93,21 @@ int pj_vgridshift_selftest (void) { PJ *P; PJ_OBS expect, a, b; double dist; + int failures = 0; /* fail on purpose: +grids parameter is mandatory*/ P = proj_create(PJ_DEFAULT_CTX, "+proj=vgridshift"); - if (0!=P) + if (0!=P) { + proj_destroy (P); return 99; + } /* fail on purpose: open non-existing grid */ P = proj_create(PJ_DEFAULT_CTX, "+proj=vgridshift +grids=nonexistinggrid.gtx"); - if (0!=P) + if (0!=P) { + proj_destroy (P); return 999; + } /* Failure most likely means the grid is missing */ P = proj_create(PJ_DEFAULT_CTX, "+proj=vgridshift +grids=egm96_15.gtx +ellps=GRS80"); @@ -136,13 +123,21 @@ int pj_vgridshift_selftest (void) { return 1; expect = a; - expect.coo.lpz.z = -36.021305084228515625; + /* Appears there is a difference between the egm96_15.gtx distributed by OSGeo4W, */ + /* and the one from http://download.osgeo.org/proj/vdatum/egm96_15/egm96_15.gtx */ + /* Was: expect.coo.lpz.z = -36.021305084228515625; (download.osgeo.org) */ + /* Was: expect.coo.lpz.z = -35.880001068115234000; (OSGeo4W) */ + /* This is annoying, but must be handled elsewhere. So for now, we check for both. */ + expect.coo.lpz.z = -36.021305084228516; + failures = 0; b = proj_trans_obs(P, PJ_FWD, a); - if (proj_xyz_dist(expect.coo.xyz, b.coo.xyz) > 1e-10) + if (proj_xyz_dist(expect.coo.xyz, b.coo.xyz) > 1e-4) failures++; + expect.coo.lpz.z = -35.880001068115234000; + if (proj_xyz_dist(expect.coo.xyz, b.coo.xyz) > 1e-4) failures++; + if (failures > 1) return 2; - - - pj_free(P); + + proj_destroy (P); return 0; } diff --git a/src/PJ_wag2.c b/src/PJ_wag2.c index 9a41ab63..0588167e 100644 --- a/src/PJ_wag2.c +++ b/src/PJ_wag2.c @@ -25,16 +25,6 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(wag2) { P->es = 0.; P->inv = s_inverse; diff --git a/src/PJ_wag3.c b/src/PJ_wag3.c index 7f5aa4ad..7f300add 100644 --- a/src/PJ_wag3.c +++ b/src/PJ_wag3.c @@ -1,6 +1,9 @@ #define PJ_LIB__ -# include <projects.h> +#include <projects.h> +#include <errno.h> + PROJ_HEAD(wag3, "Wagner III") "\n\tPCyl., Sph.\n\tlat_ts="; + #define TWOTHIRD 0.6666666666666666666667 struct pj_opaque { @@ -16,11 +19,6 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ } -#if 0 -INVERSE(s_inverse); /* spheroid */ -#endif - - static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ LP lp = {0.0,0.0}; lp.phi = xy.y; @@ -28,20 +26,13 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ return lp; } -static void freeup (PJ *P) { - pj_freeup_plain (P); - return; -} - PJ *PROJECTION(wag3) { double ts; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - { - freeup(P); - return 0; - } + return pj_default_destructor(P, ENOMEM); + P->opaque = Q; ts = pj_param (P->ctx, P->params, "rlat_ts").f; diff --git a/src/PJ_wag7.c b/src/PJ_wag7.c index d24f4e1a..9152fdea 100644 --- a/src/PJ_wag7.c +++ b/src/PJ_wag7.c @@ -19,17 +19,6 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ } -static void *freeup_new (PJ *P) { /* Destructor */ - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - - PJ *PROJECTION(wag7) { P->fwd = s_forward; P->inv = 0; diff --git a/src/PJ_wink1.c b/src/PJ_wink1.c index 320a4fb6..c1e2e909 100644 --- a/src/PJ_wink1.c +++ b/src/PJ_wink1.c @@ -1,7 +1,8 @@ #define PJ_LIB__ #include <projects.h> -PROJ_HEAD(wink1, "Winkel I") "\n\tPCyl., Sph.\n\tlat_ts="; +#include <errno.h> +PROJ_HEAD(wink1, "Winkel I") "\n\tPCyl., Sph.\n\tlat_ts="; struct pj_opaque { double cosphi1; @@ -25,25 +26,10 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(wink1) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; P->opaque->cosphi1 = cos (pj_param(P->ctx, P->params, "rlat_ts").f); diff --git a/src/PJ_wink2.c b/src/PJ_wink2.c index 4b82e423..43b6cfce 100644 --- a/src/PJ_wink2.c +++ b/src/PJ_wink2.c @@ -1,5 +1,6 @@ #define PJ_LIB__ # include <projects.h> +#include <errno.h> PROJ_HEAD(wink2, "Winkel II") "\n\tPCyl., Sph., no inv.\n\tlat_1="; @@ -33,25 +34,10 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ } -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - - PJ *PROJECTION(wink2) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; P->opaque->cosphi1 = cos(pj_param(P->ctx, P->params, "rlat_1").f); diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index c22e1b52..1be10362 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -89,6 +89,7 @@ SET(SRC_LIBPROJ_PJ PJ_lagrng.c PJ_larr.c PJ_lask.c + PJ_latlong.c PJ_lcca.c PJ_lcc.c PJ_loxim.c @@ -193,7 +194,6 @@ SET(SRC_LIBPROJ_CORE pj_initcache.c pj_inv.c pj_inv3d.c - pj_latlong.c pj_list.c pj_list.h pj_log.c diff --git a/src/makefile.vc b/src/makefile.vc index cc57d806..302389ca 100644 --- a/src/makefile.vc +++ b/src/makefile.vc @@ -25,7 +25,7 @@ misc = \ PJ_chamb.obj PJ_hammer.obj PJ_lagrng.obj PJ_larr.obj \ PJ_lask.obj PJ_nocol.obj PJ_ob_tran.obj PJ_oea.obj \ PJ_sch.obj PJ_tpeqd.obj PJ_vandg.obj PJ_vandg2.obj \ - PJ_vandg4.obj PJ_wag7.obj pj_latlong.obj PJ_krovak.obj \ + PJ_vandg4.obj PJ_wag7.obj PJ_latlong.obj PJ_krovak.obj \ pj_geocent.obj PJ_healpix.obj PJ_qsc.obj pseudo = \ diff --git a/src/pj_ctx.c b/src/pj_ctx.c index 32a3d690..7ba85e78 100644 --- a/src/pj_ctx.c +++ b/src/pj_ctx.c @@ -27,6 +27,7 @@ #include <projects.h> #include <string.h> +#include <errno.h> static projCtx_t default_context; static volatile int default_context_initialized = 0; @@ -40,6 +41,8 @@ projCtx pj_get_ctx( projPJ pj ) { if (0==pj) return pj_get_default_ctx (); + if (0==pj->ctx) + return pj_get_default_ctx (); return pj->ctx; } @@ -130,14 +133,20 @@ int pj_ctx_get_errno( projCtx ctx ) /* pj_ctx_set_errno() */ /* */ /* Also sets the global errno. */ +/* Since pj_errno makes sense in single threaded cases only, */ +/* we set it only when called on the default context. */ /************************************************************************/ void pj_ctx_set_errno( projCtx ctx, int new_errno ) { ctx->last_errno = new_errno; - if( new_errno != 0 ) - pj_errno = new_errno; + if (ctx!=pj_get_default_ctx()) + return; + if( new_errno == 0 ) + return; + pj_errno = new_errno; + errno = new_errno; } /************************************************************************/ diff --git a/src/pj_geocent.c b/src/pj_geocent.c index a00fc991..667c29bd 100644 --- a/src/pj_geocent.c +++ b/src/pj_geocent.c @@ -48,19 +48,6 @@ static LP inverse(XY xy, PJ *P) { return lp; } - -static void *freeup_new (PJ *P) { - if (0==P) - return 0; - - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - PJ *PROJECTION(geocent) { P->is_geocent = 1; P->x0 = 0.0; diff --git a/src/pj_gridlist.c b/src/pj_gridlist.c index 4193526f..1123274e 100644 --- a/src/pj_gridlist.c +++ b/src/pj_gridlist.c @@ -102,11 +102,11 @@ static int pj_gridlist_merge_gridfile( projCtx ctx, PJ_GRIDINFO **new_list; int new_max = *p_gridmax + 20; - new_list = (PJ_GRIDINFO **) pj_malloc(sizeof(void*) * new_max); + new_list = (PJ_GRIDINFO **) pj_calloc(new_max, sizeof(void *)); if( *p_gridlist != NULL ) { memcpy( new_list, *p_gridlist, - sizeof(void*) * (*p_gridmax) ); + sizeof(void *) * (*p_gridmax) ); pj_dalloc( *p_gridlist ); } @@ -194,7 +194,7 @@ PJ_GRIDINFO **pj_gridlist_from_nadgrids( projCtx ctx, const char *nadgrids, if( end_char >= sizeof(name) ) { pj_dalloc( gridlist ); - pj_ctx_set_errno( ctx, -38 ); + pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); pj_release_lock(); return NULL; } @@ -211,7 +211,7 @@ PJ_GRIDINFO **pj_gridlist_from_nadgrids( projCtx ctx, const char *nadgrids, && required ) { pj_dalloc( gridlist ); - pj_ctx_set_errno( ctx, -38 ); + pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); pj_release_lock(); return NULL; } diff --git a/src/pj_init.c b/src/pj_init.c index 08a302c6..2c2dc3ab 100644 --- a/src/pj_init.c +++ b/src/pj_init.c @@ -414,6 +414,8 @@ bum_call: return result; } + + /************************************************************************/ /* pj_init() */ /* */ @@ -438,15 +440,18 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { int found_def = 0; PJ *PIN = 0; + if (0==ctx) + ctx = pj_get_default_ctx (); + ctx->last_errno = 0; start = NULL; - /* put arguments into internal linked list */ if (argc <= 0) { - pj_ctx_set_errno( ctx, -1 ); - goto bum_call; + pj_ctx_set_errno (ctx, PJD_ERR_NO_ARGS); + return 0; } - + + /* put arguments into internal linked list */ start = curr = pj_mkparam(argv[0]); /* build parameter list and expand +init's. Does not take care of a single +init. */ @@ -458,12 +463,11 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { found_def = 0; curr = get_init(ctx, &curr, curr->next, pj_param(ctx, curr, "sinit").s, &found_def); if (!curr) - goto bum_call; + return pj_dealloc_params (ctx, start, PJD_ERR_NO_ARGS); - if (!found_def) { - pj_ctx_set_errno( ctx, -2); - goto bum_call; - } + if (!found_def) + return pj_dealloc_params (ctx, start, PJD_ERR_NO_OPTION_IN_INIT_FILE); + } else { curr = curr->next; } @@ -475,31 +479,32 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { found_def = 0; curr = get_init(ctx, &start, curr, pj_param(ctx, start, "sinit").s, &found_def); if (!curr) - goto bum_call; - if (!found_def) { - pj_ctx_set_errno( ctx, -2); - goto bum_call; - } + return pj_dealloc_params (ctx, start, PJD_ERR_NO_ARGS); + if (!found_def) + return pj_dealloc_params (ctx, start, PJD_ERR_NO_OPTION_IN_INIT_FILE); } - - if (ctx->last_errno) goto bum_call; - + + if (ctx->last_errno) + return pj_dealloc_params (ctx, start, ctx->last_errno); + /* find projection selection */ - if (!(name = pj_param(ctx, start, "sproj").s)) { - pj_ctx_set_errno( ctx, -4 ); - goto bum_call; - } + if (!(name = pj_param(ctx, start, "sproj").s)) + return pj_default_destructor (PIN, PJD_ERR_PROJ_NOT_NAMED); for (i = 0; (s = pj_list[i].id) && strcmp(name, s) ; ++i) ; - if (!s) { pj_ctx_set_errno( ctx, -5 ); goto bum_call; } - + if (!s) + return pj_dealloc_params (ctx, start, PJD_ERR_UNKNOWN_PROJECTION_ID); + /* set defaults, unless inhibited */ - if (!pj_param(ctx, start, "bno_defs").i) + if (!(pj_param(ctx, start, "bno_defs").i || (0==strcmp(pj_param(ctx, start, "sproj").s, "ob_tran")))) curr = get_defaults(ctx,&start, curr, name); proj = (PJ *(*)(PJ *)) pj_list[i].proj; /* allocate projection structure */ - if (!(PIN = (*proj)(0))) goto bum_call; + PIN = proj(0); + if (0==PIN) + return pj_dealloc_params (ctx, start, ENOMEM); + PIN->ctx = ctx; PIN->params = start; PIN->is_latlong = 0; @@ -515,19 +520,19 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { PIN->vgridlist_geoid_count = 0; /* set datum parameters */ - if (pj_datum_set(ctx, start, PIN)) goto bum_call; + if (pj_datum_set(ctx, start, PIN)) + return pj_default_destructor (PIN, PJD_ERR_MISSING_ARGS); /* set ellipsoid/sphere parameters */ if (pj_ell_set(ctx, start, &PIN->a, &PIN->es)) { pj_log (ctx, PJ_LOG_DEBUG_MINOR, "pj_init_ctx: Must specify ellipsoid or sphere"); - goto bum_call; + return pj_default_destructor (PIN, PJD_ERR_MISSING_ARGS); } PIN->a_orig = PIN->a; PIN->es_orig = PIN->es; /* Compute some ancillary ellipsoidal parameters */ - PIN->e = sqrt(PIN->es); /* eccentricity */ PIN->alpha = asin (PIN->e); /* angular eccentricity */ @@ -536,7 +541,7 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { PIN->e2s = PIN->e2 * PIN->e2; /* third eccentricity */ - PIN->e3 = sin (PIN->alpha) / sqrt(2 - sin (PIN->alpha)*sin (PIN->alpha)); + PIN->e3 = (0!=PIN->alpha)? sin (PIN->alpha) / sqrt(2 - sin (PIN->alpha)*sin (PIN->alpha)): 0; PIN->e3s = PIN->e3 * PIN->e3; /* flattening */ @@ -544,7 +549,7 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { PIN->rf = PIN->f != 0.0 ? 1.0/PIN->f: HUGE_VAL; /* second flattening */ - PIN->f2 = 1/cos (PIN->alpha) - 1; + PIN->f2 = (cos(PIN->alpha)!=0)? 1/cos (PIN->alpha) - 1: 0; PIN->rf2 = PIN->f2 != 0.0 ? 1/PIN->f2: HUGE_VAL; /* third flattening */ @@ -557,7 +562,8 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { PIN->ra = 1. / PIN->a; PIN->one_es = 1. - PIN->es; - if (PIN->one_es == 0.) { pj_ctx_set_errno( ctx, -6 ); goto bum_call; } + if (PIN->one_es == 0.) + return pj_default_destructor (PIN, PJD_ERR_ECCENTRICITY_IS_ONE); PIN->rone_es = 1./PIN->one_es; @@ -586,38 +592,28 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { /* longitude center for wrapping */ PIN->is_long_wrap_set = pj_param(ctx, start, "tlon_wrap").i; - if (PIN->is_long_wrap_set) - { + if (PIN->is_long_wrap_set) { PIN->long_wrap_center = pj_param(ctx, start, "rlon_wrap").f; /* Don't accept excessive values otherwise we might perform badly */ /* when correcting longitudes around it */ /* The test is written this way to error on long_wrap_center "=" NaN */ if( !(fabs(PIN->long_wrap_center) < 10 * M_TWOPI) ) - { - pj_ctx_set_errno( ctx, -14 ); - goto bum_call; - } + return pj_default_destructor (PIN, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT); } - + /* axis orientation */ if( (pj_param(ctx, start,"saxis").s) != NULL ) { static const char *axis_legal = "ewnsud"; const char *axis_arg = pj_param(ctx, start,"saxis").s; if( strlen(axis_arg) != 3 ) - { - pj_ctx_set_errno( ctx, PJD_ERR_AXIS ); - goto bum_call; - } + return pj_default_destructor (PIN, PJD_ERR_AXIS); if( strchr( axis_legal, axis_arg[0] ) == NULL || strchr( axis_legal, axis_arg[1] ) == NULL || strchr( axis_legal, axis_arg[2] ) == NULL) - { - pj_ctx_set_errno( ctx, PJD_ERR_AXIS ); - goto bum_call; - } - + return pj_default_destructor (PIN, PJD_ERR_AXIS); + /* it would be nice to validate we don't have on axis repeated */ strcpy( PIN->axis, axis_arg ); } @@ -631,6 +627,8 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { /* false easting and northing */ PIN->x0 = pj_param(ctx, start, "dx_0").f; PIN->y0 = pj_param(ctx, start, "dy_0").f; + PIN->z0 = pj_param(ctx, start, "dz_0").f; + PIN->t0 = pj_param(ctx, start, "dt_0").f; /* general scaling factor */ if (pj_param(ctx, start, "tk_0").i) @@ -639,26 +637,23 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { PIN->k0 = pj_param(ctx, start, "dk").f; else PIN->k0 = 1.; - if (PIN->k0 <= 0.) { - pj_ctx_set_errno( ctx, -31 ); - goto bum_call; - } + if (PIN->k0 <= 0.) + return pj_default_destructor (PIN, PJD_ERR_K_LESS_THAN_ZERO); /* set units */ s = 0; if ((name = pj_param(ctx, start, "sunits").s) != NULL) { for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i) ; - if (!s) { pj_ctx_set_errno( ctx, -7 ); goto bum_call; } + if (!s) + return pj_default_destructor (PIN, PJD_ERR_UNKNOW_UNIT_ID); s = pj_units[i].to_meter; } if (s || (s = pj_param(ctx, start, "sto_meter").s)) { PIN->to_meter = pj_strtod(s, &s); if (*s == '/') /* ratio number */ PIN->to_meter /= pj_strtod(++s, 0); - if (PIN->to_meter <= 0.0) { - pj_ctx_set_errno( ctx, -51); - goto bum_call; - } + if (PIN->to_meter <= 0.0) + return pj_default_destructor (PIN, PJD_ERR_UNIT_FACTOR_LESS_THAN_0); PIN->fr_meter = 1. / PIN->to_meter; } else PIN->to_meter = PIN->fr_meter = 1.; @@ -667,17 +662,16 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { s = 0; if ((name = pj_param(ctx, start, "svunits").s) != NULL) { for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i) ; - if (!s) { pj_ctx_set_errno( ctx, -7 ); goto bum_call; } + if (!s) + return pj_default_destructor (PIN, PJD_ERR_UNKNOW_UNIT_ID); s = pj_units[i].to_meter; } if (s || (s = pj_param(ctx, start, "svto_meter").s)) { PIN->vto_meter = pj_strtod(s, &s); if (*s == '/') /* ratio number */ PIN->vto_meter /= pj_strtod(++s, 0); - if (PIN->vto_meter <= 0.0) { - pj_ctx_set_errno( ctx, -51); - goto bum_call; - } + if (PIN->vto_meter <= 0.0) + return pj_default_destructor (PIN, PJD_ERR_UNIT_FACTOR_LESS_THAN_0); PIN->vfr_meter = 1. / PIN->vto_meter; } else { PIN->vto_meter = PIN->to_meter; @@ -704,7 +698,8 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { && *next_str == '\0' ) value = name; - if (!value) { pj_ctx_set_errno( ctx, -46 ); goto bum_call; } + if (!value) + return pj_default_destructor (PIN, PJD_ERR_UNKNOWN_PRIME_MERIDIAN); PIN->from_greenwich = dmstor_ctx(ctx,value,NULL); } else @@ -712,55 +707,15 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { /* Private object for the geodesic functions */ PIN->geod = pj_calloc (1, sizeof (struct geod_geodesic)); - if (0!=PIN->geod) - geod_init(PIN->geod, PIN->a, (1 - sqrt (1 - PIN->es))); + if (0==PIN->geod) + return pj_default_destructor (PIN, ENOMEM); + geod_init(PIN->geod, PIN->a, (1 - sqrt (1 - PIN->es))); /* projection specific initialization */ - { - /* Backup those variables so that we can clean them in case - * (*proj)(PIN) fails */ - void* gridlist = PIN->gridlist; - void* vgridlist_geoid = PIN->vgridlist_geoid; - void* catalog_name = PIN->catalog_name; - void* geod = PIN->geod; - if (!(PIN = (*proj)(PIN)) || ctx->last_errno) { - if (PIN) - pj_free(PIN); - else { - for ( ; start; start = curr) { - curr = start->next; - pj_dalloc(start); - } - if( gridlist ) - pj_dalloc( gridlist ); - if( vgridlist_geoid ) - pj_dalloc( vgridlist_geoid ); - if( catalog_name ) - pj_dalloc( catalog_name ); - if( geod ) - pj_dalloc( geod ); - } - PIN = 0; - } - } - - return PIN; - -bum_call: /* cleanup error return */ - { - if (PIN) - { - pj_free(PIN); - } - else { - for ( ; start; start = curr) { - curr = start->next; - pj_dalloc(start); - } - } + PIN = proj(PIN); + if ((0==PIN) || ctx->last_errno) return 0; - } - + return PIN; } /************************************************************************/ @@ -773,32 +728,13 @@ bum_call: /* cleanup error return */ /* P->pfree()==pj_default_destructor. */ /************************************************************************/ -void -pj_free(PJ *P) { - if (P) { - paralist *t, *n; - - /* free parameter list elements */ - for (t = P->params; t; t = n) { - n = t->next; - pj_dalloc(t); - } - - /* free grid lists */ - pj_dealloc( P->gridlist ); - pj_dealloc( P->vgridlist_geoid ); - pj_dealloc( P->catalog_name ); - - /* We used to call pj_dalloc( P->catalog ), but this will leak */ - /* memory. The safe way to clear catalog and grid is to call */ - /* pj_gc_unloadall(pj_get_default_ctx()); and pj_deallocate_grids(); */ - /* TODO: we should probably have a public pj_cleanup() method to do all */ - /* that */ - - /* free the interface to Charles Karney's geodesic library */ - pj_dealloc( P->geod ); - - /* free projection parameters */ - P->destructor (P, 0); - } +void pj_free(PJ *P) { + if (0==P) + return; + /* free projection parameters - all the hard work is done by */ + /* pj_default_destructor (in pj_malloc.c), which is supposed */ + /* to be called as the last step of the local destructor */ + /* pointed to by P->destructor. In most cases, */ + /* pj_default_destructor actually *is* what is pointed to */ + P->destructor (P, 0); } diff --git a/src/pj_malloc.c b/src/pj_malloc.c index 52cf7deb..9c69257f 100644 --- a/src/pj_malloc.c +++ b/src/pj_malloc.c @@ -40,7 +40,7 @@ ** projection system memory allocation/deallocation call with custom ** application procedures. */ -#include <projects.h> +#include "projects.h" #include <errno.h> /**********************************************************************/ @@ -52,30 +52,43 @@ https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=86420. It seems, that pj_init and similar functions incorrectly (under debian/glibs-2.3.2) assume that pj_malloc resets errno after success. pj_malloc tries to mimic this. -***********************************************************************/ - int old_errno = errno; - void *res = malloc(size); - if ( res && !old_errno ) - errno = 0; - return res; -} -/**********************************************************************/ -void pj_dalloc(void *ptr) { -/**********************************************************************/ - free(ptr); +NOTE (2017-09-29): The problem described at the bugzilla page +referred to above, is most likely a case of someone not +understanding the proper usage of errno. We should review +whether "the problem is actually a problem" in PROJ.4 code. + +Library specific allocators can be useful, and improve +interoperability, if properly used. That is, by making them +run/initialization time switchable, somewhat like the file i/o +interface. + +But as things stand, we are more likely to get benefit +from reviewing the code for proper errno usage, which is hard, +due to the presence of context local and global pj_errnos. + +Probably, these were introduced in order to support incomplete +implementations of thread local errnos at an early phase of the +implementation of multithreading support in PROJ.4). + +It is likely too late to get rid of contexts, but we can still +benefit from a better usage of errno. +***********************************************************************/ + int old_errno = errno; + void *res = malloc(size); + if ( res && !old_errno ) + errno = 0; + return res; } /**********************************************************************/ void *pj_calloc (size_t n, size_t size) { /*********************************************************************** - pj_calloc is the pj-equivalent of calloc(). It allocates space for an array of <n> elements of size <size>. The array is initialized to zeros. - ***********************************************************************/ void *res = pj_malloc (n*size); if (0==res) @@ -86,9 +99,15 @@ The array is initialized to zeros. /**********************************************************************/ +void pj_dalloc(void *ptr) { +/**********************************************************************/ + free(ptr); +} + + +/**********************************************************************/ void *pj_dealloc (void *ptr) { /*********************************************************************** - pj_dealloc supports the common use case of "clean up and return a null pointer" to signal an error in a multi level allocation: @@ -113,23 +132,55 @@ pointer" to signal an error in a multi level allocation: +/*****************************************************************************/ +void *pj_dealloc_params (projCtx ctx, paralist *start, int errlev) { +/***************************************************************************** + Companion to pj_default_destructor (below). Deallocates a linked list + of "+proj=xxx" initialization parameters. + + Also called from pj_init_ctx when encountering errors before the PJ + proper is allocated. +******************************************************************************/ + paralist *t, *n; + for (t = start; t; t = n) { + n = t->next; + pj_dealloc(t); + } + pj_ctx_set_errno (ctx, errlev); + return (void *) 0; +} + /*****************************************************************************/ void *pj_default_destructor (PJ *P, int errlev) { /* Destructor */ /***************************************************************************** Does memory deallocation for "plain" PJ objects, i.e. that vast majority of PJs where the opaque object does not contain any additionally - allocated memory. + allocated memory below the P->opaque level. ******************************************************************************/ if (0==P) return 0; - if (0!=errlev) - pj_ctx_set_errno (P->ctx, errlev); + + /* free grid lists */ + pj_dealloc( P->gridlist ); + pj_dealloc( P->vgridlist_geoid ); + pj_dealloc( P->catalog_name ); + + /* We used to call pj_dalloc( P->catalog ), but this will leak */ + /* memory. The safe way to clear catalog and grid is to call */ + /* pj_gc_unloadall(pj_get_default_ctx()); and pj_deallocate_grids(); */ + /* TODO: we should probably have a public pj_cleanup() method to do all */ + /* that */ + + /* free the interface to Charles Karney's geodesic library */ + pj_dealloc( P->geod ); - if (0==P->opaque) - return pj_dealloc (P); + /* free parameter list elements */ + pj_dealloc_params (pj_get_ctx(P), P->params, errlev); pj_dealloc (P->opaque); + if (0!=errlev) + pj_ctx_set_errno (pj_get_ctx(P), errlev); return pj_dealloc(P); } diff --git a/src/pj_mlfn.c b/src/pj_mlfn.c index 2b823026..e00f2bf1 100644 --- a/src/pj_mlfn.c +++ b/src/pj_mlfn.c @@ -19,19 +19,23 @@ #define EPS 1e-11 #define MAX_ITER 10 #define EN_SIZE 5 - double * -pj_enfn(double es) { - double t, *en; - if ((en = (double *)pj_malloc(EN_SIZE * sizeof(double))) != NULL) { - en[0] = C00 - es * (C02 + es * (C04 + es * (C06 + es * C08))); - en[1] = es * (C22 - es * (C04 + es * (C06 + es * C08))); - en[2] = (t = es * es) * (C44 - es * (C46 + es * C48)); - en[3] = (t *= es) * (C66 - es * C68); - en[4] = t * es * C88; - } /* else return NULL if unable to allocate memory */ - return en; +double *pj_enfn(double es) { + double t, *en; + + en = (double *) pj_malloc(EN_SIZE * sizeof (double)); + if (0==en) + return 0; + + en[0] = C00 - es * (C02 + es * (C04 + es * (C06 + es * C08))); + en[1] = es * (C22 - es * (C04 + es * (C06 + es * C08))); + en[2] = (t = es * es) * (C44 - es * (C46 + es * C48)); + en[3] = (t *= es) * (C66 - es * C68); + en[4] = t * es * C88; + + return en; } + double pj_mlfn(double phi, double sphi, double cphi, double *en) { cphi *= sphi; diff --git a/src/pj_obs_api.c b/src/pj_obs_api.c index acf0b577..acdf0701 100644 --- a/src/pj_obs_api.c +++ b/src/pj_obs_api.c @@ -69,7 +69,7 @@ PJ_OBS proj_obs (double x, double y, double z, double t, double o, double p, dou -/* Geodesic distance between two points with angular 2D coordinates */ +/* Geodesic distance (in meter) between two points with angular 2D coordinates */ double proj_lp_dist (const PJ *P, LP a, LP b) { double s12, azi1, azi2; /* Note: the geodesic code takes arguments in degrees */ @@ -772,5 +772,3 @@ double proj_dmstor(const char *is, char **rs) { char* proj_rtodms(char *s, double r, int pos, int neg) { return rtodms(s, r, pos, neg); } - - diff --git a/src/pj_run_selftests.c b/src/pj_run_selftests.c index 87aee76d..90193af8 100644 --- a/src/pj_run_selftests.c +++ b/src/pj_run_selftests.c @@ -40,7 +40,8 @@ int pj_run_selftests (int verbosity) { static void run_one_test (const char *mnemonic, int (testfunc)(void), int verbosity, int *n_ok, int *n_ko, int *n_stubs) { - int ret = testfunc (); + int ret; + ret = testfunc (); switch (ret) { case 0: (*n_ok)++; break; case 10000: (*n_stubs)++; break; diff --git a/src/pj_strerrno.c b/src/pj_strerrno.c index 74a7eea0..89a5a025 100644 --- a/src/pj_strerrno.c +++ b/src/pj_strerrno.c @@ -61,30 +61,36 @@ pj_err_list[] = { "non-convergent computation", /* -53 */ "missing required arguments", /* -54 */ "lat_0 = 0", /* -55 */ + "ellipsoidal usage unsupported", /* -56 */ + + /* When adding error messages, remember to update ID defines in + projects.h, and transient_error array in pj_transform */ }; char *pj_strerrno(int err) { static char note[50]; + size_t adjusted_err; if (0==err) return 0; + /* System error codes are positive */ if (err > 0) { #ifdef HAVE_STRERROR return strerror(err); #else - sprintf(note,"no system list, errno: %d\n", err); + /* Defend string boundary against exorbitantly large err values */ + /* which may occur on platforms with 64-bit ints */ + sprintf(note,"no system list, errno: %d\n", (err < 9999)? err: 9999); return note; #endif } - else /*if (err < 0)*/ { - size_t adjusted_err = - err - 1; - if (adjusted_err < (sizeof(pj_err_list) / sizeof(char *))) - return(pj_err_list[adjusted_err]); - else { - sprintf( note, "invalid projection system error (%d)", err ); - return note; - } - } + /* PROJ.4 error codes are negative */ + adjusted_err = - err - 1; + if (adjusted_err < (sizeof(pj_err_list) / sizeof(char *))) + return(pj_err_list[adjusted_err]); + + sprintf( note, "invalid projection system error (%d)", (err > -9999)? err: -9999); + return note; } diff --git a/src/pj_transform.c b/src/pj_transform.c index a842ba72..9f532188 100644 --- a/src/pj_transform.c +++ b/src/pj_transform.c @@ -54,22 +54,32 @@ static int pj_adjust_axis( projCtx ctx, const char *axis, int denormalize_flag, /* ** This table is intended to indicate for any given error code in -** the range 0 to -44, whether that error will occur for all locations (ie. +** the range 0 to -56, whether that error will occur for all locations (ie. ** it is a problem with the coordinate system as a whole) in which case the ** value would be 0, or if the problem is with the point being transformed ** in which case the value is 1. ** ** At some point we might want to move this array in with the error message ** list or something, but while experimenting with it this should be fine. +** +** +** NOTE (2017-10-01): Non-transient errors really should have resulted in a +** PJ==0 during initialization, and hence should be handled at the level +** before calling pj_transform. The only obvious example of the contrary +** appears to be the PJD_ERR_GRID_AREA case, which may also be taken to +** mean "no grids available" +** +** */ -static const int transient_error[50] = { +static const int transient_error[60] = { /* 0 1 2 3 4 5 6 7 8 9 */ /* 0 to 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 to 19 */ 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, /* 20 to 29 */ 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, /* 30 to 39 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 40 to 49 */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }; + /* 40 to 49 */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + /* 50 to 59 */ 1, 0, 1, 0, 1, 1, 1, 0, 0, 0 }; /************************************************************************/ /* pj_transform() */ diff --git a/src/proj_etmerc.c b/src/proj_etmerc.c index ff466ea8..a756a7ac 100644 --- a/src/proj_etmerc.c +++ b/src/proj_etmerc.c @@ -42,6 +42,7 @@ #define PROJ_LIB__ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -232,28 +233,12 @@ static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ } - -static void *freeup_new (PJ *P) { /* Destructor */ - if (0==P) - return 0; - if (0==P->opaque) - return pj_dealloc (P); - pj_dealloc (P->opaque); - return pj_dealloc(P); -} - -static void freeup (PJ *P) { - freeup_new (P); - return; -} - static PJ *setup(PJ *P) { /* general initialization */ double f, n, np, Z; struct pj_opaque *Q = P->opaque; if (P->es <= 0) { - proj_errno_set(P, PJD_ERR_ELLIPSOID_USE_REQUIRED); - return freeup_new(P); + return pj_default_destructor(P, PJD_ERR_ELLIPSOID_USE_REQUIRED); } /* flattening */ @@ -340,7 +325,7 @@ static PJ *setup(PJ *P) { /* general initialization */ PJ *PROJECTION(etmerc) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; return setup (P); } @@ -411,12 +396,12 @@ PJ *PROJECTION(utm) { int zone; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor (P, ENOMEM); P->opaque = Q; if (P->es == 0.0) { proj_errno_set(P, PJD_ERR_ELLIPSOID_USE_REQUIRED); - return freeup_new(P); + return pj_default_destructor(P, ENOMEM); } P->y0 = pj_param (P->ctx, P->params, "bsouth").i ? 10000000. : 0.; P->x0 = 500000.; @@ -426,8 +411,7 @@ PJ *PROJECTION(utm) { if (zone > 0 && zone <= 60) --zone; else { - proj_errno_set(P, PJD_ERR_INVALID_UTM_ZONE); - return freeup_new(P); + return pj_default_destructor(P, PJD_ERR_INVALID_UTM_ZONE); } } else /* nearest central meridian input */ diff --git a/src/proj_rouss.c b/src/proj_rouss.c index b33e7926..952e5c55 100644 --- a/src/proj_rouss.c +++ b/src/proj_rouss.c @@ -24,6 +24,7 @@ ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define PJ_LIB__ +#include <errno.h> #include <proj.h> #include "projects.h" @@ -79,21 +80,17 @@ static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static void *freeup_new (PJ *P) { /* Destructor */ +static void *destructor (PJ *P, int errlev) { if (0==P) return 0; + if (0==P->opaque) - return pj_dealloc (P); + return pj_default_destructor (P, errlev); if (P->opaque->en) pj_dealloc (P->opaque->en); - pj_dealloc (P->opaque); - return pj_dealloc(P); -} -static void freeup (PJ *P) { - freeup_new (P); - return; + return pj_default_destructor (P, ENOMEM); } @@ -102,11 +99,12 @@ PJ *PROJECTION(rouss) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) - return freeup_new (P); + return pj_default_destructor(P, ENOMEM); P->opaque = Q; if (!((Q->en = proj_mdist_ini(P->es)))) - return freeup_new(P); + return pj_default_destructor (P, ENOMEM); + es2 = sin(P->phi0); Q->s0 = proj_mdist(P->phi0, es2, cos(P->phi0), Q->en); t = 1. - (es2 = P->es * es2 * es2); @@ -149,6 +147,7 @@ PJ *PROJECTION(rouss) { P->fwd = e_forward; P->inv = e_inverse; + P->destructor = destructor; return P; } diff --git a/src/projects.h b/src/projects.h index 47f4261f..8b20edd5 100644 --- a/src/projects.h +++ b/src/projects.h @@ -332,7 +332,7 @@ struct PJconsts { **************************************************************************************/ double lam0, phi0; /* central longitude, latitude */ - double x0, y0; /* false easting and northing */ + double x0, y0, z0, t0; /* false easting and northing (and height and time) */ /************************************************************************************* @@ -524,6 +524,7 @@ struct FACTORS { #define PJD_ERR_NON_CONVERGENT -53 #define PJD_ERR_MISSING_ARGS -54 #define PJD_ERR_LAT_0_IS_ZERO -55 +#define PJD_ERR_ELLIPSOIDAL_UNSUPPORTED -56 struct projFileAPI_t; @@ -681,6 +682,8 @@ paralist *pj_clone_paralist( const paralist* ); paralist *pj_search_initcache( const char *filekey ); void pj_insert_initcache( const char *filekey, const paralist *list); paralist *pj_get_init(projCtx ctx, paralist **start, paralist *next, char *name, int *found_def); +void *pj_dealloc_params (projCtx ctx, paralist *start, int errlev); + double *pj_enfn(double); double pj_mlfn(double, double, double, double *); |
