diff options
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 *); |
