aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Knudsen <busstoptaktik@users.noreply.github.com>2017-11-10 13:55:12 +0100
committerGitHub <noreply@github.com>2017-11-10 13:55:12 +0100
commit98dd8d5b6c0f24b8e2be1a8e77e4dfac72a2dc50 (patch)
tree4c8c511010a878c34dc6126e9654a3ad720a49be /src
parent634184850a85145f20147c84f5a02fcd6df185a2 (diff)
downloadPROJ-98dd8d5b6c0f24b8e2be1a8e77e4dfac72a2dc50.tar.gz
PROJ-98dd8d5b6c0f24b8e2be1a8e77e4dfac72a2dc50.zip
Do not require needless plusses (#651)
proj_create is now indifferent whether or not proj definition terms start with a '+' character. Also, improve gie to support testing this.
Diffstat (limited to 'src')
-rw-r--r--src/gie.c40
-rw-r--r--src/proj_4D_api.c90
2 files changed, 108 insertions, 22 deletions
diff --git a/src/gie.c b/src/gie.c
index 0a344043..7bee8b67 100644
--- a/src/gie.c
+++ b/src/gie.c
@@ -259,8 +259,17 @@ int main (int argc, char **argv) {
return T.grand_ko;
}
+static int another_failure (void) {
+ T.op_ko++;
+ T.total_ko++;
+ return 0;
+}
-
+static int another_success (void) {
+ T.op_ok++;
+ T.total_ok++;
+ return 0;
+}
static int process_file (char *fname) {
@@ -434,19 +443,18 @@ static int operation (char *args) {
finish_previous_operation (args);
banner (args);
}
- /* if (0==T.op_ko)
- printf ("%d\n", (int) tol_lineno); */
+
T.op_ok = 0;
T.op_ko = 0;
direction ("forward");
- tolerance ("0.5");
+ tolerance ("0.5 mm");
if (T.P)
proj_destroy (T.P);
T.P = proj_create (0, args);
if (0==T.P)
- return errmsg(3, "Invalid operation definition!\n");
+ errmsg(3, "Invalid operation definition!\n %s\n", args);
return 0;
}
@@ -505,6 +513,8 @@ static int roundtrip (char *args) {
int ntrips;
double d, r, ans;
char *endp;
+ if (0==T.P)
+ return another_failure ();
ans = proj_strtod (args, &endp);
ntrips = (int) (endp==args? 100: fabs(ans));
d = strtod_scaled (endp, 1);
@@ -518,20 +528,16 @@ static int roundtrip (char *args) {
fprintf (T.fout, " FAILURE in %s(%d):\n", opt_strip_path (T.curr_file), (int) lineno);
fprintf (T.fout, " roundtrip deviation: %.3f mm, expected: %.3f mm\n", 1000*r, 1000*d);
}
- T.op_ko++;
- T.total_ko++;
- }
- else {
- T.op_ok++;
- T.total_ok++;
+ another_failure ();
}
+ else
+ another_success ();
return 0;
}
static int expect_message (double d, char *args) {
- T.op_ko++;
- T.total_ko++;
+ another_failure ();
if (T.verbosity < 0)
return 1;
@@ -554,8 +560,7 @@ static int expect_message (double d, char *args) {
}
static int expect_message_cannot_parse (char *args) {
- T.op_ko++;
- T.total_ko++;
+ another_failure ();
if (T.verbosity > -1) {
if (0==T.op_ko && T.verbosity < 2)
banner (T.operation);
@@ -573,6 +578,8 @@ static int expect (char *args) {
******************************************************************************/
PJ_COORD ci, co, ce;
double d;
+ if (0==T.P)
+ return another_failure ();
T.e = parse_coord (args);
if (HUGE_VAL==T.e.v[0])
@@ -609,8 +616,7 @@ static int expect (char *args) {
if (d > T.tolerance)
return expect_message (d, args);
- T.op_ok++;
- T.total_ok++;
+ another_success ();
return 0;
}
diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c
index aa076f0f..66a272f2 100644
--- a/src/proj_4D_api.c
+++ b/src/proj_4D_api.c
@@ -26,12 +26,13 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
+#include <stddef.h>
+#include <errno.h>
+#include <ctype.h>
#include <proj.h>
#include "proj_internal.h"
#include "projects.h"
#include "geodesic.h"
-#include <stddef.h>
-#include <errno.h>
/* Initialize PJ_COORD struct */
@@ -330,20 +331,99 @@ size_t proj_trans_generic (
}
-
+/*************************************************************************************/
PJ *proj_create (PJ_CONTEXT *ctx, const char *definition) {
+/**************************************************************************************
+ Create a new PJ object in the context ctx, using the given definition. If ctx==0,
+ the default context is used, if definition==0, or invalid, a null-pointer is
+ returned. The definition may use '+' as argument start indicator, as in
+ "+proj=utm +zone=32", or leave it out, as in "proj=utm zone=32"
+**************************************************************************************/
+ PJ *P;
+ char *args, **argv;
+ int argc, i, j, n;
+
if (0==ctx)
ctx = pj_get_default_ctx ();
- return pj_init_plus_ctx (ctx, definition);
+
+ /* make a copy that we can manipulate */
+ n = (int) strlen (definition);
+ args = (char *) malloc (n + 1);
+ if (0==args)
+ return 0;
+ strcpy (args, definition);
+
+ /* all-in-one: count args, eliminate superfluous whitespace, 0-terminate substrings */
+ for (i = j = argc = 0; i < n; ) {
+ /* skip prefix whitespace */
+ while (isspace (args[i]))
+ i++;
+
+ /* skip at most one prefix '+' */
+ if ('+'==args[i])
+ i++;
+
+ /* whitespace after a '+' is a syntax error - but by Postel's prescription, we ignore and go on */
+ if (isspace (args[i]))
+ continue;
+
+ /* move a whitespace delimited text string to the left, skipping over superfluous whitespace */
+ while ((0!=args[i]) && (!isspace (args[i])))
+ args[j++] = args[i++];
+
+ /* terminate string - if that makes j pass i (often the case for first arg), let i catch up */
+ args[j++] = 0;
+ if (i < j)
+ i = j;
+
+ /* we finished another arg */
+ argc++;
+
+ /* skip postfix whitespace */
+ while (isspace (args[i]))
+ i++;
+ }
+
+ /* turn the massaged input into an array of strings */
+ argv = (char **) calloc (argc, sizeof (char *));
+ if (0==argv)
+ return pj_dealloc (args);
+
+ argv[0] = args;
+ for (i = 0, j = 1; i < n; i++) {
+ if (0==args[i])
+ argv[j++] = args + (i + 1);
+ if (j==argc)
+ break;
+ }
+
+ /* ...and let pj_init_ctx do the hard work */
+ P = pj_init_ctx (ctx, argc, argv);
+ pj_dealloc (argv);
+ pj_dealloc (args);
+ return P;
}
+
+
+/*************************************************************************************/
PJ *proj_create_argv (PJ_CONTEXT *ctx, int argc, char **argv) {
+/**************************************************************************************
+Create a new PJ object in the context ctx, using the given definition argument
+array argv. If ctx==0, the default context is used, if definition==0, or invalid,
+a null-pointer is returned. The definition arguments may use '+' as argument start
+indicator, as in {"+proj=utm", "+zone=32"}, or leave it out, as in {"proj=utm",
+"zone=32"}.
+**************************************************************************************/
+ if (0==argv)
+ return 0;
if (0==ctx)
ctx = pj_get_default_ctx ();
return pj_init_ctx (ctx, argc, argv);
}
+
/*****************************************************************************/
PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *srid_from, const char *srid_to, PJ_AREA *area) {
/******************************************************************************
@@ -461,7 +541,7 @@ int proj_errno_reset (PJ *P) {
}
-/* Create a new context - or provide a pointer to the default context */
+/* Create a new context */
PJ_CONTEXT *proj_context_create (void) {
return pj_ctx_alloc ();
}