aboutsummaryrefslogtreecommitdiff
path: root/src/PJ_minimal.c
diff options
context:
space:
mode:
authorThomas Knudsen <thokn@sdfe.dk>2017-09-27 13:56:34 +0200
committerThomas Knudsen <thokn@sdfe.dk>2017-10-06 11:39:27 +0200
commit664577ced6a8e4074b1f53af82b5ae5d1d189eac (patch)
treea29d4a6c0842bb87df63fc913502c3b6c5b097a5 /src/PJ_minimal.c
parent0495fdca92fc620d44572ce1e4e871f57f968198 (diff)
downloadPROJ-664577ced6a8e4074b1f53af82b5ae5d1d189eac.tar.gz
PROJ-664577ced6a8e4074b1f53af82b5ae5d1d189eac.zip
Enable default destructor for all PJ objects.
In most cases memory deallocation is completely removed from the code since it can be handled by the default destructor. In a few special cases a local destructor overrides the default destructor and makes sure that locally allocated memored is cleaned up correctly. Move all deallocation from pj_free to pj_default_destructor Rename pj_latlong.c to fit with the conventional format PJ_latlong.c - freeup was missed here due to wrong naming Clean up pj_init to avoid double deallocation; Also resolve #576 by adding z_0 and t_0 options in pj_init, while cleaning Add a prototype for dealloc_params Added missing errno.h include in pj_ctx.c Temporarily removing ob_tran from testvarious, to be sure that is where the trouble is Make PJ_ob_tran.c use proper initialization for the chained projection proj=ob_tran: make it clear, that we disallow ellipsoidal projections, and, for improved backwards compatibility, turns off default settings, which could inject unwanted ellipsoid definitions ... then also remove the ellipsoid definition from the testvarious test case - which is probably buggy anyway Work around cs2cs spherical init bug in testvarious; Forbid defs for ob_tran in pj_init
Diffstat (limited to 'src/PJ_minimal.c')
-rw-r--r--src/PJ_minimal.c204
1 files changed, 0 insertions, 204 deletions
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;
-}