aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Evers <kristianevers@gmail.com>2018-03-15 08:29:49 +0100
committerGitHub <noreply@github.com>2018-03-15 08:29:49 +0100
commit16618bf5763aa235e01755d4865b455ccb14c928 (patch)
tree41c5920fd36155375648dff8fd96d197308091f3
parent30090445886a8f6842028b5ab20601f4c7336fe2 (diff)
parent3cc7b4c62382650f9bf00365b25f8fa7f6eed603 (diff)
downloadPROJ-16618bf5763aa235e01755d4865b455ccb14c928.tar.gz
PROJ-16618bf5763aa235e01755d4865b455ccb14c928.zip
Merge pull request #860 from rouault/cppcheck
Fix various issues spotted by cppcheck and clang static analyzer
-rw-r--r--.travis.yml9
-rwxr-xr-xscripts/cppcheck.sh350
-rw-r--r--src/PJ_chamb.c2
-rw-r--r--src/PJ_goode.c4
-rw-r--r--src/PJ_igh.c2
-rw-r--r--src/PJ_imw_p.c4
-rw-r--r--src/PJ_isea.c10
-rw-r--r--src/PJ_lsat.c2
-rw-r--r--src/PJ_misrsom.c2
-rw-r--r--src/PJ_ob_tran.c8
-rw-r--r--src/PJ_pipeline.c10
-rw-r--r--src/cct.c4
-rw-r--r--src/cs2cs.c7
-rw-r--r--src/geod_set.c2
-rw-r--r--src/geodesic.c39
-rw-r--r--src/geodtest.c2
-rw-r--r--src/nad2bin.c8
-rw-r--r--src/pj_apply_gridshift.c6
-rw-r--r--src/pj_apply_vgridshift.c1
-rw-r--r--src/pj_datum_set.c10
-rw-r--r--src/pj_gridcatalog.c2
-rw-r--r--src/pj_gridinfo.c43
-rw-r--r--src/pj_init.c3
-rw-r--r--src/pj_internal.c2
-rw-r--r--src/pj_param.c9
-rw-r--r--src/proj.c4
-rw-r--r--src/proj_4D_api.c13
-rwxr-xr-xtravis/csa/after_success.sh5
-rwxr-xr-xtravis/csa/before_install.sh8
-rwxr-xr-xtravis/csa/install.sh11
-rwxr-xr-xtravis/linux_gcc/before_install.sh10
31 files changed, 505 insertions, 87 deletions
diff --git a/.travis.yml b/.travis.yml
index e9eeb033..b33d4c2f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,6 +8,7 @@ cache:
matrix:
fast_finish: true
include:
+
- os: linux
compiler: gcc
language: c
@@ -39,6 +40,14 @@ matrix:
- BUILD_NAME=mingw32
- DETAILS="mingw32"
+ - os: linux
+ compiler: gcc
+ language: c
+ dist: trusty
+ env:
+ - BUILD_NAME=csa
+ - DETAILS="CLang Static Analyzer"
+
allow_failures:
- env: BUILD_NAME=mingw32
diff --git a/scripts/cppcheck.sh b/scripts/cppcheck.sh
new file mode 100755
index 00000000..df939c06
--- /dev/null
+++ b/scripts/cppcheck.sh
@@ -0,0 +1,350 @@
+#!/bin/bash
+# Note: tested with cppcheck 1.72 as shipped with Ubuntu 16.04
+# as well as with cppcheck 1.76.1
+
+LOG_FILE=/tmp/cppcheck_proj.txt
+
+echo "" > ${LOG_FILE}
+for dirname in src; do
+ echo "Running cppcheck on $dirname... (can be long)"
+ if ! cppcheck --inline-suppr --template='{file}:{line},{severity},{id},{message}' \
+ --enable=all --inconclusive --std=posix \
+ -DCPPCHECK \
+ $dirname \
+ -j 8 >>${LOG_FILE} 2>&1 ; then
+ echo "cppcheck failed"
+ exit 1
+ fi
+done
+
+ret_code=0
+
+grep -v "unmatchedSuppression" ${LOG_FILE} > ${LOG_FILE}.tmp
+mv ${LOG_FILE}.tmp ${LOG_FILE}
+
+if grep "null pointer" ${LOG_FILE} ; then
+ echo "Null pointer check failed"
+ ret_code=1
+fi
+
+if grep "duplicateBreak" ${LOG_FILE} ; then
+ echo "duplicateBreak check failed"
+ ret_code=1
+fi
+
+if grep "duplicateBranch" ${LOG_FILE} ; then
+ echo "duplicateBranch check failed"
+ ret_code=1
+fi
+
+if grep "uninitMemberVar" ${LOG_FILE} ; then
+ echo "uninitMemberVar check failed"
+ ret_code=1
+fi
+
+if grep "useInitializationList" ${LOG_FILE} ; then
+ echo "uninitMemberVar check failed"
+ ret_code=1
+fi
+
+if grep "clarifyCalculation" ${LOG_FILE} ; then
+ echo "clarifyCalculation check failed"
+ ret_code=1
+fi
+
+if grep "invalidPrintfArgType_uint" ${LOG_FILE} ; then
+ echo "invalidPrintfArgType_uint check failed"
+ ret_code=1
+fi
+
+if grep "catchExceptionByValue" ${LOG_FILE} ; then
+ echo "catchExceptionByValue check failed"
+ ret_code=1
+fi
+
+if grep "memleakOnRealloc" ${LOG_FILE} ; then
+ echo "memleakOnRealloc check failed"
+ ret_code=1
+fi
+
+if grep "arrayIndexOutOfBoundsCond" ${LOG_FILE} ; then
+ echo "arrayIndexOutOfBoundsCond check failed"
+ ret_code=1
+fi
+
+if grep "arrayIndexOutOfBounds," ${LOG_FILE} ; then
+ echo "arrayIndexOutOfBounds check failed"
+ ret_code=1
+fi
+
+if grep "syntaxError" ${LOG_FILE} | grep -v "is invalid C code" ; then
+ echo "syntaxError check failed"
+ ret_code=1
+fi
+
+if grep "memleak," ${LOG_FILE} ; then
+ echo "memleak check failed"
+ ret_code=1
+fi
+
+if grep "eraseDereference" ${LOG_FILE} ; then
+ echo "eraseDereference check failed"
+ ret_code=1
+fi
+
+if grep "memsetClass," ${LOG_FILE} ; then
+ echo "memsetClass check failed"
+ ret_code=1
+fi
+
+if grep "uninitvar," ${LOG_FILE} ; then
+ echo "uninitvar check failed"
+ ret_code=1
+fi
+
+if grep "uninitdata," ${LOG_FILE} ; then
+ echo "uninitdata check failed"
+ ret_code=1
+fi
+
+if grep "va_list_usedBeforeStarted" ${LOG_FILE} ; then
+ echo "va_list_usedBeforeStarted check failed"
+ ret_code=1
+fi
+
+if grep "duplInheritedMember" ${LOG_FILE} ; then
+ echo "duplInheritedMember check failed"
+ ret_code=1
+fi
+
+if grep "terminateStrncpy" ${LOG_FILE} ; then
+ echo "terminateStrncpy check failed"
+ ret_code=1
+fi
+
+if grep "operatorEqVarError" ${LOG_FILE} ; then
+ echo "operatorEqVarError check failed"
+ ret_code=1
+fi
+
+if grep "uselessAssignmentPtrArg" ${LOG_FILE} ; then
+ echo "uselessAssignmentPtrArg check failed"
+ ret_code=1
+fi
+
+if grep "bufferNotZeroTerminated" ${LOG_FILE} ; then
+ echo "bufferNotZeroTerminated check failed"
+ ret_code=1
+fi
+
+if grep "sizeofDivisionMemfunc" ${LOG_FILE} ; then
+ echo "sizeofDivisionMemfunc check failed"
+ ret_code=1
+fi
+
+if grep "selfAssignment" ${LOG_FILE} ; then
+ echo "selfAssignment check failed"
+ ret_code=1
+fi
+
+if grep "invalidPrintfArgType_sint" ${LOG_FILE} ; then
+ echo "invalidPrintfArgType_sint check failed"
+ ret_code=1
+fi
+
+if grep "redundantAssignInSwitch" ${LOG_FILE} ; then
+ echo "redundantAssignInSwitch check failed"
+ ret_code=1
+fi
+
+if grep "publicAllocationError" ${LOG_FILE} ; then
+ echo "publicAllocationError check failed"
+ ret_code=1
+fi
+
+if grep "invalidScanfArgType_int" ${LOG_FILE} ; then
+ echo "invalidScanfArgType_int check failed"
+ ret_code=1
+fi
+
+if grep "invalidscanf," ${LOG_FILE} ; then
+ echo "invalidscanf check failed"
+ ret_code=1
+fi
+
+if grep "moduloAlwaysTrueFalse" ${LOG_FILE} ; then
+ echo "moduloAlwaysTrueFalse check failed"
+ ret_code=1
+fi
+
+if grep "charLiteralWithCharPtrCompare" ${LOG_FILE} ; then
+ echo "charLiteralWithCharPtrCompare check failed"
+ ret_code=1
+fi
+
+if grep "noConstructor" ${LOG_FILE} ; then
+ echo "noConstructor check failed"
+ ret_code=1
+fi
+
+if grep "noExplicitConstructor" ${LOG_FILE} ; then
+ echo "noExplicitConstructor check failed"
+ ret_code=1
+fi
+
+if grep "noCopyConstructor" ${LOG_FILE} ; then
+ echo "noCopyConstructor check failed"
+ ret_code=1
+fi
+
+if grep "passedByValue" ${LOG_FILE} ; then
+ echo "passedByValue check failed"
+ ret_code=1
+fi
+
+if grep "postfixOperator" ${LOG_FILE} ; then
+ echo "postfixOperator check failed"
+ ret_code=1
+fi
+
+if grep "redundantCopy" ${LOG_FILE} ; then
+ echo "redundantCopy check failed"
+ ret_code=1
+fi
+
+if grep "stlIfStrFind" ${LOG_FILE} ; then
+ echo "stlIfStrFind check failed"
+ ret_code=1
+fi
+
+if grep "functionStatic" ${LOG_FILE} ; then
+ echo "functionStatic check failed"
+ ret_code=1
+fi
+
+if grep "knownConditionTrueFalse" ${LOG_FILE} ; then
+ echo "knownConditionTrueFalse check failed"
+ ret_code=1
+fi
+
+if grep "arrayIndexThenCheck" ${LOG_FILE} ; then
+ echo "arrayIndexThenCheck check failed"
+ ret_code=1
+fi
+
+if grep "unusedPrivateFunction" ${LOG_FILE} ; then
+ echo "unusedPrivateFunction check failed"
+ ret_code=1
+fi
+
+if grep "redundantCondition" ${LOG_FILE} ; then
+ echo "redundantCondition check failed"
+ ret_code=1
+fi
+
+if grep "unusedStructMember" ${LOG_FILE} ; then
+ echo "unusedStructMember check failed"
+ ret_code=1
+fi
+
+if grep "multiCondition" ${LOG_FILE} ; then
+ echo "multiCondition check failed"
+ ret_code=1
+fi
+
+if grep "duplicateExpression" ${LOG_FILE} ; then
+ echo "duplicateExpression check failed"
+ ret_code=1
+fi
+
+if grep "operatorEq" ${LOG_FILE} ; then
+ echo "operatorEq check failed"
+ ret_code=1
+fi
+
+if grep "truncLongCastAssignment" ${LOG_FILE} ; then
+ echo "truncLongCastAssignment check failed"
+ ret_code=1
+fi
+
+if grep "exceptRethrowCopy" ${LOG_FILE} ; then
+ echo "exceptRethrowCopy check failed"
+ ret_code=1
+fi
+
+if grep "unusedVariable" ${LOG_FILE} ; then
+ echo "unusedVariable check failed"
+ ret_code=1
+fi
+
+if grep "unsafeClassCanLeak" ${LOG_FILE} ; then
+ echo "unsafeClassCanLeak check failed"
+ ret_code=1
+fi
+
+if grep "unsignedLessThanZero" ${LOG_FILE} ; then
+ echo "unsignedLessThanZero check failed"
+ ret_code=1
+fi
+
+if grep "unpreciseMathCall" ${LOG_FILE} ; then
+ echo "unpreciseMathCall check failed"
+ ret_code=1
+fi
+
+if grep "unreachableCode" ${LOG_FILE} ; then
+ echo "unreachableCode check failed"
+ ret_code=1
+fi
+
+if grep "clarifyCondition" ${LOG_FILE} ; then
+ echo "clarifyCondition check failed"
+ ret_code=1
+fi
+
+if grep "redundantIfRemove" ${LOG_FILE} ; then
+ echo "redundantIfRemove check failed"
+ ret_code=1
+fi
+
+if grep "unassignedVariable" ${LOG_FILE} ; then
+ echo "unassignedVariable check failed"
+ ret_code=1
+fi
+
+if grep "redundantAssignment" ${LOG_FILE} ; then
+ echo "redundantAssignment check failed"
+ ret_code=1
+fi
+
+if grep "unreadVariable" ${LOG_FILE} ; then
+ echo "unreadVariable check failed"
+ ret_code=1
+fi
+
+if grep "AssignmentAddressToInteger" ${LOG_FILE} ; then
+ echo "AssignmentAddressToInteger check failed"
+ ret_code=1
+fi
+
+
+# Check any remaining errors
+if grep "error," ${LOG_FILE} | grep -v "uninitvar" | \
+ grep -v "memleak," | grep -v "memleakOnRealloc" | \
+ grep -v "is invalid C code" ; then
+
+ echo "Errors check failed"
+ ret_code=1
+fi
+
+# Check any remaining warnings
+if grep "warning," ${LOG_FILE}; then
+ echo "Warnings check failed"
+ ret_code=1
+fi
+
+if [ ${ret_code} = 0 ]; then
+ echo "cppcheck succeeded"
+fi
+
+exit ${ret_code}
diff --git a/src/PJ_chamb.c b/src/PJ_chamb.c
index ca9c5edc..571bdf10 100644
--- a/src/PJ_chamb.c
+++ b/src/PJ_chamb.c
@@ -50,7 +50,7 @@ static double lc(projCtx ctx, double b,double c,double a) {
static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
- XY xy = {0.0,0.0};
+ XY xy;
struct pj_opaque *Q = P->opaque;
double sinphi, cosphi, a;
VECT v[3];
diff --git a/src/PJ_goode.c b/src/PJ_goode.c
index 1554fd41..65761c4b 100644
--- a/src/PJ_goode.c
+++ b/src/PJ_goode.c
@@ -17,7 +17,7 @@ struct pj_opaque {
static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
- XY xy = {0.0,0.0};
+ XY xy;
struct pj_opaque *Q = P->opaque;
if (fabs(lp.phi) <= PHI_LIM)
@@ -31,7 +31,7 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */
- LP lp = {0.0,0.0};
+ LP lp;
struct pj_opaque *Q = P->opaque;
if (fabs(xy.y) <= PHI_LIM)
diff --git a/src/PJ_igh.c b/src/PJ_igh.c
index d1d684e7..bb97a8b5 100644
--- a/src/PJ_igh.c
+++ b/src/PJ_igh.c
@@ -36,7 +36,7 @@ struct pj_opaque {
static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
- XY xy = {0.0,0.0};
+ XY xy;
struct pj_opaque *Q = P->opaque;
int z;
diff --git a/src/PJ_imw_p.c b/src/PJ_imw_p.c
index b731f656..c7939d3e 100644
--- a/src/PJ_imw_p.c
+++ b/src/PJ_imw_p.c
@@ -91,10 +91,8 @@ static XY loc_for(LP lp, PJ *P, double *yc) {
static XY e_forward (LP lp, PJ *P) { /* Ellipsoidal, forward */
- XY xy = {0.0,0.0};
double yc;
-
- xy = loc_for(lp, P, &yc);
+ XY xy = loc_for(lp, P, &yc);
return (xy);
}
diff --git a/src/PJ_isea.c b/src/PJ_isea.c
index f08a83fa..57412a38 100644
--- a/src/PJ_isea.c
+++ b/src/PJ_isea.c
@@ -139,12 +139,6 @@ struct isea_geo {
double lon, lat;
};
-struct isea_address {
- int type; /* enum isea_address_form */
- int number;
- double x,y; /* or i,j or lon,lat depending on type */
-};
-
/* ENDINC */
enum snyder_polyhedron {
@@ -155,7 +149,9 @@ enum snyder_polyhedron {
};
struct snyder_constants {
- double g, G, theta, ea_w, ea_a, ea_b, g_w, g_a, g_b;
+ double g, G, theta;
+ /* cppcheck-suppress unusedStructMember */
+ double ea_w, ea_a, ea_b, g_w, g_a, g_b;
};
/* TODO put these in radians to avoid a later conversion */
diff --git a/src/PJ_lsat.c b/src/PJ_lsat.c
index 4b77f3d6..7e1567e1 100644
--- a/src/PJ_lsat.c
+++ b/src/PJ_lsat.c
@@ -61,8 +61,6 @@ static XY e_forward (LP lp, PJ *P) { /* Ellipsoidal, forward */
sav = lampp;
lamtp = lp.lam + Q->p22 * lampp;
cl = cos(lamtp);
- if (fabs(cl) < TOL)
- lamtp -= TOL;
if( cl < 0 )
fac = lampp + sin(lampp) * M_HALFPI;
else
diff --git a/src/PJ_misrsom.c b/src/PJ_misrsom.c
index c25ca597..b9b97117 100644
--- a/src/PJ_misrsom.c
+++ b/src/PJ_misrsom.c
@@ -78,8 +78,6 @@ static XY e_forward (LP lp, PJ *P) { /* Ellipsoidal, forward */
sav = lampp;
lamtp = lp.lam + Q->p22 * lampp;
cl = cos(lamtp);
- if (fabs(cl) < TOL)
- lamtp -= TOL;
if( cl < 0 )
fac = lampp + sin(lampp) * M_HALFPI;
else
diff --git a/src/PJ_ob_tran.c b/src/PJ_ob_tran.c
index e6971138..8b13eb65 100644
--- a/src/PJ_ob_tran.c
+++ b/src/PJ_ob_tran.c
@@ -48,11 +48,11 @@ static XY t_forward(LP lp, PJ *P) { /* spheroid */
static LP o_inverse(XY xy, PJ *P) { /* spheroid */
- LP lp = {0.0,0.0};
+
struct pj_opaque *Q = P->opaque;
double coslam, sinphi, cosphi;
- lp = Q->link->inv(xy, Q->link);
+ LP lp = Q->link->inv(xy, Q->link);
if (lp.lam != HUGE_VAL) {
coslam = cos(lp.lam -= Q->lamp);
sinphi = sin(lp.phi);
@@ -66,11 +66,11 @@ static LP o_inverse(XY xy, PJ *P) { /* spheroid */
static LP t_inverse(XY xy, PJ *P) { /* spheroid */
- LP lp = {0.0,0.0};
+
struct pj_opaque *Q = P->opaque;
double cosphi, t;
- lp = Q->link->inv(xy, Q->link);
+ LP lp = Q->link->inv(xy, Q->link);
if (lp.lam != HUGE_VAL) {
cosphi = cos(lp.phi);
t = lp.lam - Q->lamp;
diff --git a/src/PJ_pipeline.c b/src/PJ_pipeline.c
index 3890f552..2791a4e8 100644
--- a/src/PJ_pipeline.c
+++ b/src/PJ_pipeline.c
@@ -106,7 +106,6 @@ PROJ_HEAD(pipeline, "Transformation pipeline manager");
/* Projection specific elements for the PJ object */
struct pj_opaque {
- int reversible;
int steps;
char **argv;
char **current_argv;
@@ -287,7 +286,9 @@ static void set_ellipsoid(PJ *P) {
/* Break the linked list after the global args */
attachment = 0;
for (cur = P->params; cur != 0; cur = cur->next)
- if (strcmp("step", cur->next->param) == 0) {
+ /* cur->next will always be non 0 given argv_sentinel presence, */
+ /* but this is far from being obvious for a static analyzer */
+ if (cur->next != 0 && strcmp(argv_sentinel, cur->next->param) == 0) {
attachment = cur->next;
cur->next = 0;
break;
@@ -311,7 +312,10 @@ static void set_ellipsoid(PJ *P) {
geod_init(P->geod, P->a, (1 - sqrt (1 - P->es)));
/* Re-attach the dangling list */
- cur->next = attachment;
+ /* Note: cur will always be non 0 given argv_sentinel presence, */
+ /* but this is far from being obvious for a static analyzer */
+ if( cur != 0 )
+ cur->next = attachment;
proj_errno_restore (P, err);
}
diff --git a/src/cct.c b/src/cct.c
index 1853a962..8096986d 100644
--- a/src/cct.c
+++ b/src/cct.c
@@ -202,6 +202,7 @@ int main(int argc, char **argv) {
}
if (opt_given (o, "c")) {
+ /* 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"));
@@ -232,6 +233,8 @@ int main(int argc, char **argv) {
/* fail if an inverse operation is not available */
if (!proj_pj_info(P).has_inverse) {
fprintf (stderr, "Inverse operation not available\n");
+ if (stdout != fout)
+ fclose (fout);
return 1;
}
/* We have no API call for inverting an operation, so we brute force it. */
@@ -306,6 +309,7 @@ int main(int argc, char **argv) {
if (stdout != fout)
fclose (fout);
free (o);
+ free (buf);
return 0;
}
diff --git a/src/cs2cs.c b/src/cs2cs.c
index 730d37ee..de3259d2 100644
--- a/src/cs2cs.c
+++ b/src/cs2cs.c
@@ -263,6 +263,7 @@ int main(int argc, char **argv)
} else
emess(1,"invalid list option: l%c",arg[1]);
exit(0);
+ /* cppcheck-suppress duplicateBreak */
continue; /* artificial */
case 'e': /* error line alternative */
if (--argc <= 0)
@@ -446,10 +447,8 @@ int main(int argc, char **argv)
emess_dat.File_name = 0;
}
- if( fromProj != NULL )
- pj_free( fromProj );
- if( toProj != NULL )
- pj_free( toProj );
+ pj_free( fromProj );
+ pj_free( toProj );
pj_deallocate_grids();
diff --git a/src/geod_set.c b/src/geod_set.c
index 26a86b61..571a7d20 100644
--- a/src/geod_set.c
+++ b/src/geod_set.c
@@ -19,7 +19,7 @@ geod_set(int argc, char **argv) {
start = curr = pj_mkparam(argv[0]);
if (!curr)
emess(1, "memory allocation failed");
- for (i = 1; i < argc; ++i) {
+ for (i = 1; curr != 0 && i < argc; ++i) {
curr->next = pj_mkparam(argv[i]);
if (!curr->next)
emess(1, "memory allocation failed");
diff --git a/src/geodesic.c b/src/geodesic.c
index 23557b5c..40dffbc1 100644
--- a/src/geodesic.c
+++ b/src/geodesic.c
@@ -94,6 +94,7 @@ static void Init() {
#else
{
real minus1 = -1;
+ /* cppcheck-suppress wrongmathcall */
NaN = sqrt(minus1);
}
#endif
@@ -585,7 +586,7 @@ real geod_genposition(const struct geod_geodesicline* l,
salp2 = l->salp0; calp2 = l->calp0 * csig2; /* No need to normalize */
if (outmask & GEOD_DISTANCE)
- s12 = flags & GEOD_ARCMODE ?
+ s12 = (flags & GEOD_ARCMODE) ?
l->b * ((1 + l->A1m1) * sig12 + AB1) :
s12_a12;
@@ -594,7 +595,7 @@ real geod_genposition(const struct geod_geodesicline* l,
/* tan(omg2) = sin(alp0) * tan(sig2) */
somg2 = l->salp0 * ssig2; comg2 = csig2; /* No need to normalize */
/* omg12 = omg2 - omg1 */
- omg12 = flags & GEOD_LONG_UNROLL
+ omg12 = (flags & GEOD_LONG_UNROLL)
? E * (sig12
- (atan2( ssig2, csig2) - atan2( l->ssig1, l->csig1))
+ (atan2(E * somg2, comg2) - atan2(E * l->somg1, l->comg1)))
@@ -604,7 +605,7 @@ real geod_genposition(const struct geod_geodesicline* l,
( sig12 + (SinCosSeries(TRUE, ssig2, csig2, l->C3a, nC3-1)
- l->B31));
lon12 = lam12 / degree;
- lon2 = flags & GEOD_LONG_UNROLL ? l->lon1 + lon12 :
+ lon2 = (flags & GEOD_LONG_UNROLL) ? l->lon1 + lon12 :
AngNormalize(AngNormalize(l->lon1) + AngNormalize(lon12));
}
@@ -657,24 +658,24 @@ real geod_genposition(const struct geod_geodesicline* l,
S12 = l->c2 * atan2(salp12, calp12) + l->A4 * (B42 - l->B41);
}
- if (outmask & GEOD_LATITUDE)
+ if ((outmask & GEOD_LATITUDE) && plat2)
*plat2 = lat2;
- if (outmask & GEOD_LONGITUDE)
+ if ((outmask & GEOD_LONGITUDE) && plon2)
*plon2 = lon2;
- if (outmask & GEOD_AZIMUTH)
+ if ((outmask & GEOD_AZIMUTH) && pazi2)
*pazi2 = azi2;
- if (outmask & GEOD_DISTANCE)
+ if ((outmask & GEOD_DISTANCE) && ps12)
*ps12 = s12;
- if (outmask & GEOD_REDUCEDLENGTH)
+ if ((outmask & GEOD_REDUCEDLENGTH) && pm12)
*pm12 = m12;
if (outmask & GEOD_GEODESICSCALE) {
if (pM12) *pM12 = M12;
if (pM21) *pM21 = M21;
}
- if (outmask & GEOD_AREA)
+ if ((outmask & GEOD_AREA) && pS12)
*pS12 = S12;
- return flags & GEOD_ARCMODE ? s12_a12 : sig12 / degree;
+ return (flags & GEOD_ARCMODE) ? s12_a12 : sig12 / degree;
}
void geod_setdistance(struct geod_geodesicline* l, real s13) {
@@ -689,7 +690,7 @@ static void geod_setarc(struct geod_geodesicline* l, real a13) {
void geod_gensetdistance(struct geod_geodesicline* l,
unsigned flags, real s13_a13) {
- flags & GEOD_ARCMODE ?
+ (flags & GEOD_ARCMODE) ?
geod_setarc(l, s13_a13) :
geod_setdistance(l, s13_a13);
}
@@ -718,7 +719,7 @@ real geod_gendirect(const struct geod_geodesic* g,
geod_lineinit(&l, g, lat1, lon1, azi1,
/* Automatically supply GEOD_DISTANCE_IN if necessary */
outmask |
- (flags & GEOD_ARCMODE ? GEOD_NONE : GEOD_DISTANCE_IN));
+ ((flags & GEOD_ARCMODE) ? GEOD_NONE : GEOD_DISTANCE_IN));
return geod_genposition(&l, flags, s12_a12,
plat2, plon2, pazi2, ps12, pm12, pM12, pM21, pS12);
}
@@ -845,8 +846,8 @@ static real geod_geninverse_int(const struct geod_geodesic* g,
csig1 * csig2 + ssig1 * ssig2);
Lengths(g, g->n, sig12, ssig1, csig1, dn1, ssig2, csig2, dn2,
cbet1, cbet2, &s12x, &m12x, 0,
- outmask & GEOD_GEODESICSCALE ? &M12 : 0,
- outmask & GEOD_GEODESICSCALE ? &M21 : 0,
+ (outmask & GEOD_GEODESICSCALE) ? &M12 : 0,
+ (outmask & GEOD_GEODESICSCALE) ? &M21 : 0,
Ca);
/* Add the check for sig12 since zero length geodesics might yield m12 <
* 0. Test case was
@@ -969,8 +970,8 @@ static real geod_geninverse_int(const struct geod_geodesic* g,
}
Lengths(g, eps, sig12, ssig1, csig1, dn1, ssig2, csig2, dn2,
cbet1, cbet2, &s12x, &m12x, 0,
- outmask & GEOD_GEODESICSCALE ? &M12 : 0,
- outmask & GEOD_GEODESICSCALE ? &M21 : 0, Ca);
+ (outmask & GEOD_GEODESICSCALE) ? &M12 : 0,
+ (outmask & GEOD_GEODESICSCALE) ? &M21 : 0, Ca);
m12x *= g->b;
s12x *= g->b;
a12 = sig12 / degree;
@@ -1126,7 +1127,7 @@ real SinCosSeries(boolx sinp, real sinx, real cosx, const real c[], int n) {
real ar, y0, y1;
c += (n + sinp); /* Point to one beyond last element */
ar = 2 * (cosx - sinx) * (cosx + sinx); /* 2 * cos(2 * x) */
- y0 = n & 1 ? *--c : 0; y1 = 0; /* accumulators for sum */
+ y0 = (n & 1) ? *--c : 0; y1 = 0; /* accumulators for sum */
/* Now n is even */
n /= 2;
while (n--) {
@@ -1893,7 +1894,7 @@ void geod_polygon_addedge(const struct geod_geodesic* g,
struct geod_polygon* p,
real azi, real s) {
if (p->num) { /* Do nothing is num is zero */
- real lat, lon, S12 = 0; /* Initialize S12 to stop Visual Studio warning */
+ real lat = 0, lon = 0, S12 = 0; /* Initialize S12 to stop Visual Studio warning */
geod_gendirect(g, p->lat, p->lon, azi, GEOD_LONG_UNROLL, s,
&lat, &lon, 0,
0, 0, 0, 0, p->polyline ? 0 : &S12);
@@ -2030,7 +2031,7 @@ unsigned geod_polygon_testedge(const struct geod_geodesic* g,
tempsum = p->A[0];
crossings = p->crossings;
{
- real lat, lon, s12, S12;
+ real lat = 0, lon = 0, s12, S12 = 0;
geod_gendirect(g, p->lat, p->lon, azi, GEOD_LONG_UNROLL, s,
&lat, &lon, 0,
0, 0, 0, 0, &S12);
diff --git a/src/geodtest.c b/src/geodtest.c
index de729407..8cc48134 100644
--- a/src/geodtest.c
+++ b/src/geodtest.c
@@ -341,6 +341,7 @@ static int GeodSolve14() {
int result = 0;
{
double minus1 = -1;
+ /* cppcheck-suppress wrongmathcall */
nan = sqrt(minus1);
}
geod_init(&g, wgs84_a, wgs84_f);
@@ -482,6 +483,7 @@ static int GeodSolve55() {
int result = 0;
{
double minus1 = -1;
+ /* cppcheck-suppress wrongmathcall */
nan = sqrt(minus1);
}
geod_init(&g, wgs84_a, wgs84_f);
diff --git a/src/nad2bin.c b/src/nad2bin.c
index 03a55326..dfc4e2dd 100644
--- a/src/nad2bin.c
+++ b/src/nad2bin.c
@@ -77,7 +77,7 @@ int main(int argc, char **argv) {
/* ==================================================================== */
for( i = 1; i < argc; i++ )
{
- if( strcmp(argv[i],"-f") == 0 && i < argc-1 )
+ if( i < argc-1 && strcmp(argv[i],"-f") == 0 )
{
format = argv[++i];
}
@@ -103,6 +103,7 @@ int main(int argc, char **argv) {
perror("fgets");
exit(1);
}
+ /* cppcheck-suppress invalidscanf */
if ( EOF == scanf("%d %d %*d %lf %lf %lf %lf", &ct.lim.lam, &ct.lim.phi,
&ct.ll.lam, &ct.del.lam, &ct.ll.phi, &ct.del.phi) ) {
perror("scanf");
@@ -119,6 +120,7 @@ int main(int argc, char **argv) {
ct.del.phi *= DEG_TO_RAD;
/* load table */
for (p = ct.cvs, i = 0; i < ct.lim.phi; ++i) {
+ /* cppcheck-suppress invalidscanf */
if ( EOF == scanf("%d:%ld %ld", &ichk, &laml, &phil) ) {
perror("scanf on row");
exit(1);
@@ -131,6 +133,7 @@ int main(int argc, char **argv) {
t.phi = (float) (phil * U_SEC_TO_RAD);
*p++ = t;
for (j = 1; j < ct.lim.lam; ++j) {
+ /* cppcheck-suppress invalidscanf */
if ( EOF == scanf("%ld %ld", &lam, &phi) ) {
perror("scanf on column");
exit(1);
@@ -177,7 +180,9 @@ int main(int argc, char **argv) {
exit(2);
}
+ /* cppcheck-suppress sizeofCalculation */
STATIC_ASSERT( MAX_TAB_ID == 80 );
+ /* cppcheck-suppress sizeofCalculation */
STATIC_ASSERT( sizeof(pj_int32) == 4 ); /* for ct.lim.lam/phi */
memset( header, 0, sizeof(header) );
@@ -273,6 +278,7 @@ int main(int argc, char **argv) {
ur.lam = ct.ll.lam + (ct.lim.lam-1) * ct.del.lam;
ur.phi = ct.ll.phi + (ct.lim.phi-1) * ct.del.phi;
+ /* cppcheck-suppress sizeofCalculation */
STATIC_ASSERT( sizeof(nGSCount) == 4 );
memset( achHeader, 0, sizeof(achHeader) );
diff --git a/src/pj_apply_gridshift.c b/src/pj_apply_gridshift.c
index a2267cbd..c503ec0b 100644
--- a/src/pj_apply_gridshift.c
+++ b/src/pj_apply_gridshift.c
@@ -206,10 +206,10 @@ int pj_apply_gridshift_3( projCtx ctx, PJ_GRIDINFO **tables, int grid_count,
if( ct != NULL )
{
output = nad_cvt( input, inverse, ct );
- }
- if ( output.lam != HUGE_VAL && debug_count++ < 20 )
- pj_log( ctx, PJ_LOG_DEBUG_MINOR, "pj_apply_gridshift(): used %s", ct->id );
+ if ( output.lam != HUGE_VAL && debug_count++ < 20 )
+ pj_log( ctx, PJ_LOG_DEBUG_MINOR, "pj_apply_gridshift(): used %s", ct->id );
+ }
if ( output.lam == HUGE_VAL )
{
diff --git a/src/pj_apply_vgridshift.c b/src/pj_apply_vgridshift.c
index 5a40ddfd..1b32c0f6 100644
--- a/src/pj_apply_vgridshift.c
+++ b/src/pj_apply_vgridshift.c
@@ -41,6 +41,7 @@ static double read_vgrid_value( PJ *defn, LP input, int *gridlist_count_p, PJ_GR
int grid_ix2, grid_iy2;
float *cvs;
/* do not deal with NaN coordinates */
+ /* cppcheck-suppress duplicateExpression */
if( input.phi != input.phi || input.lam != input.lam )
itable = *gridlist_count_p;
diff --git a/src/pj_datum_set.c b/src/pj_datum_set.c
index f9027bb0..374beda2 100644
--- a/src/pj_datum_set.c
+++ b/src/pj_datum_set.c
@@ -61,7 +61,10 @@ int pj_datum_set(projCtx ctx, paralist *pl, PJ *projdef)
/* find the end of the list, so we can add to it */
for (curr = pl; curr && curr->next ; curr = curr->next) {}
-
+
+ /* cannot happen in practice, but makes static analyzers happy */
+ if( !curr ) return -1;
+
/* find the datum definition */
for (i = 0; (s = pj_datums[i].id) && strcmp(name, s) ; ++i) {}
@@ -81,12 +84,15 @@ int pj_datum_set(projCtx ctx, paralist *pl, PJ *projdef)
if( pj_datums[i].defn && strlen(pj_datums[i].defn) > 0 )
curr = curr->next = pj_mkparam(pj_datums[i].defn);
+
+ (void)curr; /* make clang static analyzer happy */
}
/* -------------------------------------------------------------------- */
/* Check for nadgrids parameter. */
/* -------------------------------------------------------------------- */
- if( (nadgrids = pj_param(ctx, pl,"snadgrids").s) != NULL )
+ nadgrids = pj_param(ctx, pl,"snadgrids").s;
+ if( nadgrids != NULL )
{
/* We don't actually save the value separately. It will continue
to exist int he param list for use in pj_apply_gridshift.c */
diff --git a/src/pj_gridcatalog.c b/src/pj_gridcatalog.c
index c0194146..8777185b 100644
--- a/src/pj_gridcatalog.c
+++ b/src/pj_gridcatalog.c
@@ -260,7 +260,7 @@ PJ_GRIDINFO *pj_gc_findgrid( projCtx ctx, PJ_GridCatalog *catalog, int after,
break;
}
- if( iEntry == catalog->entry_count )
+ if( entry == NULL )
{
if( grid_date )
*grid_date = 0.0;
diff --git a/src/pj_gridinfo.c b/src/pj_gridinfo.c
index 664effdc..9a8b3dd5 100644
--- a/src/pj_gridinfo.c
+++ b/src/pj_gridinfo.c
@@ -66,6 +66,19 @@ static void swap_words( unsigned char *data, int word_size, int word_count )
}
/************************************************************************/
+/* to_double() */
+/* */
+/* Returns a double from the pointed data. */
+/************************************************************************/
+
+static double to_double( unsigned char* data )
+{
+ double d;
+ memcpy(&d, data, sizeof(d));
+ return d;
+}
+
+/************************************************************************/
/* pj_gridinfo_free() */
/************************************************************************/
@@ -422,7 +435,9 @@ static int pj_gridinfo_init_ntv2( projCtx ctx, PAFile fid, PJ_GRIDINFO *gilist )
int num_subfiles, subfile;
int must_swap;
+ /* cppcheck-suppress sizeofCalculation */
STATIC_ASSERT( sizeof(pj_int32) == 4 );
+ /* cppcheck-suppress sizeofCalculation */
STATIC_ASSERT( sizeof(double) == 8 );
/* -------------------------------------------------------------------- */
@@ -508,14 +523,14 @@ static int pj_gridinfo_init_ntv2( projCtx ctx, PAFile fid, PJ_GRIDINFO *gilist )
strncpy( ct->id, (const char *) header + 8, 8 );
ct->id[8] = '\0';
- ct->ll.lam = - *((double *) (header+7*16+8)); /* W_LONG */
- ct->ll.phi = *((double *) (header+4*16+8)); /* S_LAT */
+ ct->ll.lam = - to_double(header+7*16+8); /* W_LONG */
+ ct->ll.phi = to_double(header+4*16+8); /* S_LAT */
- ur.lam = - *((double *) (header+6*16+8)); /* E_LONG */
- ur.phi = *((double *) (header+5*16+8)); /* N_LAT */
+ ur.lam = - to_double(header+6*16+8); /* E_LONG */
+ ur.phi = to_double(header+5*16+8); /* N_LAT */
- ct->del.lam = *((double *) (header+9*16+8));
- ct->del.phi = *((double *) (header+8*16+8));
+ ct->del.lam = to_double(header+9*16+8);
+ ct->del.phi = to_double(header+8*16+8);
ct->lim.lam = (pj_int32) (fabs(ur.lam-ct->ll.lam)/ct->del.lam + 0.5) + 1;
ct->lim.phi = (pj_int32) (fabs(ur.phi-ct->ll.phi)/ct->del.phi + 0.5) + 1;
@@ -645,7 +660,9 @@ static int pj_gridinfo_init_ntv1( projCtx ctx, PAFile fid, PJ_GRIDINFO *gi )
struct CTABLE *ct;
LP ur;
+ /* cppcheck-suppress sizeofCalculation */
STATIC_ASSERT( sizeof(pj_int32) == 4 );
+ /* cppcheck-suppress sizeofCalculation */
STATIC_ASSERT( sizeof(double) == 8 );
/* -------------------------------------------------------------------- */
@@ -689,12 +706,12 @@ static int pj_gridinfo_init_ntv1( projCtx ctx, PAFile fid, PJ_GRIDINFO *gi )
}
strcpy( ct->id, "NTv1 Grid Shift File" );
- ct->ll.lam = - *((double *) (header+72));
- ct->ll.phi = *((double *) (header+24));
- ur.lam = - *((double *) (header+56));
- ur.phi = *((double *) (header+40));
- ct->del.lam = *((double *) (header+104));
- ct->del.phi = *((double *) (header+88));
+ ct->ll.lam = - to_double(header+72);
+ ct->ll.phi = to_double(header+24);
+ ur.lam = - to_double(header+56);
+ ur.phi = to_double(header+40);
+ ct->del.lam = to_double(header+104);
+ ct->del.phi = to_double(header+88);
ct->lim.lam = (pj_int32) (fabs(ur.lam-ct->ll.lam)/ct->del.lam + 0.5) + 1;
ct->lim.phi = (pj_int32) (fabs(ur.phi-ct->ll.phi)/ct->del.phi + 0.5) + 1;
@@ -730,7 +747,9 @@ static int pj_gridinfo_init_gtx( projCtx ctx, PAFile fid, PJ_GRIDINFO *gi )
double xorigin,yorigin,xstep,ystep;
int rows, columns;
+ /* cppcheck-suppress sizeofCalculation */
STATIC_ASSERT( sizeof(pj_int32) == 4 );
+ /* cppcheck-suppress sizeofCalculation */
STATIC_ASSERT( sizeof(double) == 8 );
/* -------------------------------------------------------------------- */
diff --git a/src/pj_init.c b/src/pj_init.c
index 16408ebb..2d549317 100644
--- a/src/pj_init.c
+++ b/src/pj_init.c
@@ -67,6 +67,9 @@ static paralist *string_to_paralist (PJ_CONTEXT *ctx, char *definition) {
c++;
}
+ if( next == 0 )
+ return 0;
+
/* Terminate list and return */
next->next = 0;
return first;
diff --git a/src/pj_internal.c b/src/pj_internal.c
index 40f06bd6..1204d27a 100644
--- a/src/pj_internal.c
+++ b/src/pj_internal.c
@@ -343,7 +343,7 @@ array.
if (0==argc)
return p;
- for (i = n = 0; i < argc; i++) {
+ for (i = 0; i < argc; i++) {
strcat (p, argv[i]);
strcat (p, " ");
}
diff --git a/src/pj_param.c b/src/pj_param.c
index 133f3ea6..b52ac940 100644
--- a/src/pj_param.c
+++ b/src/pj_param.c
@@ -131,17 +131,20 @@ PROJVALUE pj_param (projCtx ctx, paralist *pl, const char *opt) {
/* Not found */
if (0==pl) {
+ /* Return value after the switch, so that the return path is */
+ /* taken in all cases */
switch (type) {
case 'b': case 'i':
value.i = 0;
- return value;
+ break;
case 'd': case 'r':
value.f = 0.;
- return value;
+ break;
case 's':
value.s = 0;
- return value;
+ break;
}
+ return value;
}
/* Found parameter - now find its value */
diff --git a/src/proj.c b/src/proj.c
index 1c86854e..c3b604c9 100644
--- a/src/proj.c
+++ b/src/proj.c
@@ -221,9 +221,6 @@ static void vprocess(FILE *fid) {
if (*s == 'I' || *s == 'i') {
linvers = 1;
++s;
- } else if (*s == 'I' || *s == 'i') {
- linvers = 0;
- ++s;
} else
linvers = inverse;
@@ -413,6 +410,7 @@ int main(int argc, char **argv) {
} else
emess(1,"invalid list option: l%c",arg[1]);
exit(0);
+ /* cppcheck-suppress duplicateBreak */
continue; /* artificial */
case 'e': /* error line alternative */
if (--argc <= 0)
diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c
index f96dd67d..58b3d835 100644
--- a/src/proj_4D_api.c
+++ b/src/proj_4D_api.c
@@ -632,14 +632,18 @@ PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *srid_from, const char
******************************************************************************/
PJ *P;
char buffer[512];
+ size_t len;
/* area not in use yet, suppressing warning */
(void)area;
strcpy(buffer, "+proj=pipeline +step +init=");
- strncat(buffer, srid_from, 512-strlen(buffer));
- strncat(buffer, " +inv +step +init=", 512-strlen(buffer));
- strncat(buffer, srid_to, 512-strlen(buffer));
+ len = strlen(buffer);
+ strncat(buffer + len, srid_from, sizeof(buffer)-1-len);
+ len += strlen(buffer + len);
+ strncat(buffer + len, " +inv +step +init=", sizeof(buffer)-1-len);
+ len += strlen(buffer + len);
+ strncat(buffer + len, srid_to, sizeof(buffer)-1-len);
P = proj_create(ctx, buffer);
@@ -1004,7 +1008,8 @@ PJ_INIT_INFO proj_init_info(const char *initname){
key[64] = 0;
strncat(key, ":metadata", 9);
strcpy(param, "+init=");
- strncat(param, key, 73);
+ /* The +strlen(param) avoids a cppcheck false positive warning */
+ strncat(param + strlen(param), key, sizeof(param)-1-strlen(param));
start = pj_mkparam(param);
pj_expand_init(ctx, start);
diff --git a/travis/csa/after_success.sh b/travis/csa/after_success.sh
new file mode 100755
index 00000000..9618f673
--- /dev/null
+++ b/travis/csa/after_success.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+set -e
+
+# nothing
diff --git a/travis/csa/before_install.sh b/travis/csa/before_install.sh
new file mode 100755
index 00000000..b8c7260b
--- /dev/null
+++ b/travis/csa/before_install.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+set -e
+
+./travis/before_install.sh
+
+wget http://releases.llvm.org/6.0.0/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz
+tar xJf clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz
diff --git a/travis/csa/install.sh b/travis/csa/install.sh
new file mode 100755
index 00000000..4b82606f
--- /dev/null
+++ b/travis/csa/install.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+set -e
+
+# prepare build files
+./autogen.sh
+
+./clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04/bin/scan-build -o scanbuildoutput -plist -v ./configure
+./clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04/bin/scan-build -o scanbuildoutput -plist -v make -j3
+
+if grep -r "\.c" scanbuildoutput | grep "<string>" | grep -v "<key>"; then echo "error" && /bin/false; else echo "ok"; fi
diff --git a/travis/linux_gcc/before_install.sh b/travis/linux_gcc/before_install.sh
index 87877629..c1d119d8 100755
--- a/travis/linux_gcc/before_install.sh
+++ b/travis/linux_gcc/before_install.sh
@@ -4,16 +4,10 @@
sudo apt-get install -y cppcheck
-cppcheck --inline-suppr --template='{file}:{line},{severity},{id},{message}' --enable=all --inconclusive --std=posix src/*.c 2>/tmp/cppcheck.txt
-
-grep "error," /tmp/cppcheck.txt
-if [[ $? -eq 0 ]] ; then
- echo "cppcheck failed"
- exit 1
-fi
-
set -e
+scripts/cppcheck.sh
+
pip install --user cpp-coveralls
./travis/docker.sh