diff options
Diffstat (limited to 'src/pj_init.c')
| -rw-r--r-- | src/pj_init.c | 208 |
1 files changed, 72 insertions, 136 deletions
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); } |
