Skip to content

Commit

Permalink
Merge 71d7a87 into b4b15d0
Browse files Browse the repository at this point in the history
  • Loading branch information
kbevers committed Apr 8, 2018
2 parents b4b15d0 + 71d7a87 commit 2058605
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 51 deletions.
50 changes: 50 additions & 0 deletions docs/source/development/reference/datatypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -744,3 +744,53 @@ Info structures
.. c:member:: char PJ_INIT_INFO.lastupdate
Date of last update of the init-file.


Logging
-------------------------------------------------------------------------------

.. c:type:: PJ_LOG_LEVEL
Enum of logging levels in PROJ. Used to set the logging level in PROJ.
Usually using :c:func:`proj_log_level`.

.. c:member:: PJ_LOG_NONE
Don't log anything.

.. c:member:: PJ_LOG_ERROR
Log only errors.

.. c:member:: PJ_LOG_DEBUG
Log errors and additional debug information.

.. c:member:: PJ_LOG_TRACE
Highest logging level. Log everything including very detailed debug
information.

.. c:member:: PJ_LOG_TELL
Special logging level that when used in :c:func:`proj_log_level`
will return the current logging level set in PROJ.

.. versionadded:: 5.1.0

.. c:type:: PJ_LOG_FUNC
Function prototype for the logging function used by PROJ.
Defined as

.. code-block:: C
typedef void (*PJ_LOG_FUNCTION)(void *, int, const char *);
where the :c:type:`void` pointer references a data structure used by the
calling application, the :c:type:`int` is used to set the logging level
and the :c:type:`const char` pointer is the string that will be logged
by the function.


.. versionadded:: 5.1.0
28 changes: 28 additions & 0 deletions docs/source/development/reference/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,34 @@ Change the error-state of :c:data:`P` to `err`.
.. note:: Available from version 5.1.0.
Logging
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.. c:function:: PJ_LOG_LEVEL proj_log_level (PJ_CONTEXT *ctx, PJ_LOG_LEVEL level)
Get and set logging level for a given context. Changes the log level to
:c:data:`level` and returns the previous logging level. If called with
:c:data:`level` set to :c:type:`PJ_LOG_TELL` the function returns the current
logging level without changing it.
:param PJ_CONTEXT* ctx: Threading context.
:param PJ_LOG_LEVEL level: New logging level.
:returns: :c:type:`PJ_LOG_LEVEL`
.. versionadded:: 5.1.0
.. c:function:: void proj_log_func (PJ_CONTEXT *ctx, void *app_data, PJ_LOG_FUNCTION logf)
Override the internal log function of PROJ.
:param PJ_CONTEXT* ctx: Threading context.
:param void* app_data: Pointer to data structure used by the calling application.
:param PJ_LOG_FUNCTION logf: Log function that overrides the PROJ log function.
.. versionadded:: 5.1.0
Info functions
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Expand Down
100 changes: 73 additions & 27 deletions src/cct.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ Thomas Knudsen, thokn@sdfe.dk, 2016-05-25/2017-10-26
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

#include "proj.h"
#include "proj_internal.h"
Expand All @@ -86,13 +87,14 @@ Thomas Knudsen, thokn@sdfe.dk, 2016-05-25/2017-10-26
/* Prototypes for functions in proj_strtod.c */
double proj_strtod(const char *str, char **endptr);
double proj_atof(const char *str);
static void logger(void *data, int level, const char *msg);
static void print(PJ_LOG_LEVEL verbosity, const char *fmt, ...);

/* Prototypes from functions in this file */
char *column (char *buf, int n);
PJ_COORD parse_input_line (char *buf, int *columns, double fixed_height, double fixed_time);



static const char usage[] = {
"--------------------------------------------------------------------------------\n"
"Usage: %s [-options]... [+operator_specs]... infile...\n"
Expand Down Expand Up @@ -149,19 +151,66 @@ static const char usage[] = {
"--------------------------------------------------------------------------------\n"
};


static void logger(void *data, int level, const char *msg) {
FILE *stream;
int log_tell = proj_log_level(PJ_DEFAULT_CTX, PJ_LOG_TELL);

stream = (FILE *) data;

/* if we use PJ_LOG_NONE we always want to print stuff to stream */
if (level == PJ_LOG_NONE) {
fprintf(stream, "%s", msg);
return;
}

/* should always print to stderr if level == PJ_LOG_ERROR */
if (level == PJ_LOG_ERROR) {
fprintf(stderr, "%s", msg);
return;
}

/* otherwise only print if log level set by user is high enough */
if (level <= log_tell)
fprintf(stream, "%s", msg);
}

FILE *fout;

static void print(PJ_LOG_LEVEL log_level, const char *fmt, ...) {

va_list args;
char *msg_buf;

va_start( args, fmt );

msg_buf = (char *) malloc(100000);
if( msg_buf == NULL )
return;

vsprintf( msg_buf, fmt, args );

logger((void *) fout, log_level, msg_buf);

va_end( args );
free( msg_buf );
}


int main(int argc, char **argv) {
PJ *P;
PJ_COORD point;
PJ_PROJ_INFO info;
OPTARGS *o;
FILE *fout = stdout;
char *buf;
int nfields = 4, direction = 1, verbose;
double fixed_z = HUGE_VAL, fixed_time = HUGE_VAL;
int columns_xyzt[] = {1, 2, 3, 4};
const char *longflags[] = {"v=verbose", "h=help", "I=inverse", "version", 0};
const char *longkeys[] = {"o=output", "c=columns", "z=height", "t=time", 0};

fout = stdout;

o = opt_parse (argc, argv, "hvI", "cozt", longflags, longkeys);
if (0==o)
return 0;
Expand All @@ -171,26 +220,26 @@ int main(int argc, char **argv) {
return 0;
}


direction = opt_given (o, "I")? -1: 1;
verbose = opt_given (o, "v");

verbose = MIN(opt_given (o, "v"), 3); /* log level can't be larger than 3 */
proj_log_level (PJ_DEFAULT_CTX, verbose);
proj_log_func (PJ_DEFAULT_CTX, (void *) fout, logger);

if (opt_given (o, "version")) {
fprintf (stdout, "%s: %s\n", o->progname, pj_get_release ());
print (PJ_LOG_NONE, "%s: %s\n", o->progname, pj_get_release ());
return 0;
}

if (opt_given (o, "o"))
fout = fopen (opt_arg (o, "output"), "wt");
if (0==fout) {
fprintf (stderr, "%s: Cannot open '%s' for output\n", o->progname, opt_arg (o, "output"));
print (PJ_LOG_ERROR, "%s: Cannot open '%s' for output\n", o->progname, opt_arg (o, "output"));
free (o);
return 1;
}
if (verbose > 3)
fprintf (fout, "%s: Running in very verbose mode\n", o->progname);


print (PJ_LOG_TRACE, "%s: Running in very verbose mode\n", o->progname);

if (opt_given (o, "z")) {
fixed_z = proj_atof (opt_arg (o, "z"));
Expand All @@ -206,7 +255,7 @@ int main(int argc, char **argv) {
/* cppcheck-suppress invalidscanf */
int ncols = sscanf (opt_arg (o, "c"), "%d,%d,%d,%d", columns_xyzt, columns_xyzt+1, columns_xyzt+2, columns_xyzt+3);
if (ncols != nfields) {
fprintf (stderr, "%s: Too few input columns given: '%s'\n", o->progname, opt_arg (o, "c"));
print (PJ_LOG_ERROR, "%s: Too few input columns given: '%s'\n", o->progname, opt_arg (o, "c"));
free (o);
if (stdout != fout)
fclose (fout);
Expand All @@ -217,23 +266,21 @@ int main(int argc, char **argv) {
/* Setup transformation */
P = proj_create_argv (0, o->pargc, o->pargv);
if ((0==P) || (0==o->pargc)) {
fprintf (stderr, "%s: Bad transformation arguments - (%s)\n '%s -h' for help\n",
print (PJ_LOG_ERROR, "%s: Bad transformation arguments - (%s)\n '%s -h' for help\n",
o->progname, pj_strerrno (proj_errno(P)), o->progname);
free (o);
if (stdout != fout)
fclose (fout);
return 1;
}

if (verbose > 4) {
info = proj_pj_info (P);
fprintf (stdout, "Final: %s argc=%d pargc=%d\n", info.definition, argc, o->pargc);
}
info = proj_pj_info (P);
print (PJ_LOG_TRACE, "Final: %s argc=%d pargc=%d\n", info.definition, argc, o->pargc);

if (direction==-1) {
/* fail if an inverse operation is not available */
if (!proj_pj_info(P).has_inverse) {
fprintf (stderr, "Inverse operation not available\n");
if (!info.has_inverse) {
print (PJ_LOG_ERROR, "Inverse operation not available\n");
if (stdout != fout)
fclose (fout);
return 1;
Expand All @@ -246,7 +293,7 @@ int main(int argc, char **argv) {
/* Allocate input buffer */
buf = calloc (1, 10000);
if (0==buf) {
fprintf (stderr, "%s: Out of memory\n", o->progname);
print (PJ_LOG_ERROR, "%s: Out of memory\n", o->progname);
pj_free (P);
free (o);
if (stdout != fout)
Expand All @@ -261,7 +308,7 @@ int main(int argc, char **argv) {
void *ret = fgets (buf, 10000, o->input);
opt_eof_handler (o);
if (0==ret) {
fprintf (stderr, "Read error in record %d\n", (int) o->record_index);
print (PJ_LOG_ERROR, "Read error in record %d\n", (int) o->record_index);
continue;
}
point = parse_input_line (buf, columns_xyzt, fixed_z, fixed_time);
Expand All @@ -270,14 +317,13 @@ int main(int argc, char **argv) {

/* if it's a comment or blank line, we reflect it */
if (c && ((*c=='\0') || (*c=='#'))) {
fprintf (fout, "%s\n", buf);
print (PJ_LOG_NONE, "%s\n", buf);
continue;
}

/* otherwise, it must be a syntax error */
fprintf (fout, "# Record %d UNREADABLE: %s", (int) o->record_index, buf);
if (verbose)
fprintf (stderr, "%s: Could not parse file '%s' line %d\n", o->progname, opt_filename (o), opt_record (o));
print (PJ_LOG_NONE, "# Record %d UNREADABLE: %s", (int) o->record_index, buf);
print (PJ_LOG_ERROR, "%s: Could not parse file '%s' line %d\n", o->progname, opt_filename (o), opt_record (o));
continue;
}

Expand All @@ -290,8 +336,8 @@ int main(int argc, char **argv) {

if (HUGE_VAL==point.xyzt.x) {
/* transformation error */
fprintf (fout, "# Record %d TRANSFORMATION ERROR: %s (%s)",
(int) o->record_index, buf, pj_strerrno (proj_errno(P)));
print (PJ_LOG_NONE, "# Record %d TRANSFORMATION ERROR: %s (%s)",
(int) o->record_index, buf, pj_strerrno (proj_errno(P)));
proj_errno_restore (P, err);
continue;
}
Expand All @@ -301,10 +347,10 @@ int main(int argc, char **argv) {
if (proj_angular_output (P, direction)) {
point.lpzt.lam = proj_todeg (point.lpzt.lam);
point.lpzt.phi = proj_todeg (point.lpzt.phi);
fprintf (fout, "%14.10f %14.10f %12.4f %12.4f\n", point.xyzt.x, point.xyzt.y, point.xyzt.z, point.xyzt.t);
print (PJ_LOG_NONE, "%14.10f %14.10f %12.4f %12.4f\n", point.xyzt.x, point.xyzt.y, point.xyzt.z, point.xyzt.t);
}
else
fprintf (fout, "%13.4f %13.4f %12.4f %12.4f\n", point.xyzt.x, point.xyzt.y, point.xyzt.z, point.xyzt.t);
print (PJ_LOG_NONE, "%13.4f %13.4f %12.4f %12.4f\n", point.xyzt.x, point.xyzt.y, point.xyzt.z, point.xyzt.t);
}

if (stdout != fout)
Expand Down
9 changes: 2 additions & 7 deletions src/pj_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,23 +364,18 @@ to that context.
return;
}






/* logging */

/* pj_vlog resides in pj_log.c and relates to pj_log as vsprintf relates to sprintf */
void pj_vlog( projCtx ctx, int level, const char *fmt, va_list args );


/***************************************************************************************/
enum proj_log_level proj_log_level (PJ_CONTEXT *ctx, enum proj_log_level log_level) {
PJ_LOG_LEVEL proj_log_level (PJ_CONTEXT *ctx, PJ_LOG_LEVEL log_level) {
/****************************************************************************************
Set logging level 0-3. Higher number means more debug info. 0 turns it off
****************************************************************************************/
enum proj_log_level previous;
PJ_LOG_LEVEL previous;
if (0==ctx)
ctx = pj_get_default_ctx();
if (0==ctx)
Expand Down
15 changes: 14 additions & 1 deletion src/proj.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,17 @@ struct PJ_INIT_INFO {
char lastupdate[16]; /* Date of last update in YYYY-MM-DD format */
};

typedef enum PJ_LOG_LEVEL {
PJ_LOG_NONE = 0,
PJ_LOG_ERROR = 1,
PJ_LOG_DEBUG = 2,
PJ_LOG_TRACE = 3,
PJ_LOG_TELL = 4,
PJ_LOG_DEBUG_MAJOR = 2, /* for proj_api.h compatibility */
PJ_LOG_DEBUG_MINOR = 3 /* for proj_api.h compatibility */
} PJ_LOG_LEVEL;

typedef void (*PJ_LOG_FUNCTION)(void *, int, const char *);


/* The context type - properly namespaced synonym for projCtx */
Expand Down Expand Up @@ -342,7 +353,6 @@ double proj_xyz_dist (PJ_COORD a, PJ_COORD b);
PJ_COORD proj_geod (const PJ *P, PJ_COORD a, PJ_COORD b);



/* Set or read error level */
int proj_context_errno (PJ_CONTEXT *ctx);
int proj_errno (const PJ *P);
Expand All @@ -351,6 +361,9 @@ int proj_errno_reset (const PJ *P);
int proj_errno_restore (const PJ *P, int err);
const char* proj_errno_string (int err);

PJ_LOG_LEVEL proj_log_level (PJ_CONTEXT *ctx, PJ_LOG_LEVEL level);
void proj_log_func (PJ_CONTEXT *ctx, void *app_data, PJ_LOG_FUNCTION logf);

/* Scaling and angular distortion factors */
PJ_FACTORS proj_factors(PJ *P, PJ_COORD lp);

Expand Down

0 comments on commit 2058605

Please sign in to comment.