diff options
| author | Kristian Evers <kristianevers@gmail.com> | 2019-03-27 07:35:32 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-03-27 07:35:32 +0100 |
| commit | cc0326748ba04cac6d9409543e6fad112bca36b6 (patch) | |
| tree | a422e160995a0ecb117e145d7b48e77e975a1d4c /src | |
| parent | 4754220ec8e3febd3d96e8096df8291c7a78fdb1 (diff) | |
| parent | c05a91da2e9e008d77bd148d4de62045f9f149c8 (diff) | |
| download | PROJ-cc0326748ba04cac6d9409543e6fad112bca36b6.tar.gz PROJ-cc0326748ba04cac6d9409543e6fad112bca36b6.zip | |
Merge pull request #1373 from rouault/coverity_fixes
Coverity fixes
Diffstat (limited to 'src')
| -rw-r--r-- | src/4D_api.cpp | 1 | ||||
| -rw-r--r-- | src/apply_gridshift.cpp | 3 | ||||
| -rw-r--r-- | src/apply_vgridshift.cpp | 9 | ||||
| -rw-r--r-- | src/apps/cct.cpp | 2 | ||||
| -rw-r--r-- | src/apps/cs2cs.cpp | 7 | ||||
| -rw-r--r-- | src/apps/emess.cpp | 2 | ||||
| -rw-r--r-- | src/apps/gie.cpp | 1 | ||||
| -rw-r--r-- | src/apps/optargpm.h | 5 | ||||
| -rw-r--r-- | src/apps/proj.cpp | 2 | ||||
| -rw-r--r-- | src/apps/projinfo.cpp | 17 | ||||
| -rw-r--r-- | src/gridcatalog.cpp | 10 | ||||
| -rw-r--r-- | src/gridinfo.cpp | 6 | ||||
| -rw-r--r-- | src/iso19111/c_api.cpp | 85 | ||||
| -rw-r--r-- | src/iso19111/coordinateoperation.cpp | 7 | ||||
| -rw-r--r-- | src/iso19111/crs.cpp | 8 | ||||
| -rw-r--r-- | src/iso19111/factory.cpp | 12 | ||||
| -rw-r--r-- | src/iso19111/io.cpp | 7 | ||||
| -rw-r--r-- | src/nad_init.cpp | 4 | ||||
| -rw-r--r-- | src/proj_internal.h | 6 |
19 files changed, 92 insertions, 102 deletions
diff --git a/src/4D_api.cpp b/src/4D_api.cpp index d0b2748e..81e16600 100644 --- a/src/4D_api.cpp +++ b/src/4D_api.cpp @@ -1365,6 +1365,7 @@ static char *path_append (char *buf, const char *app, size_t *buf_size) { pj_dealloc (buf); buf = p; } + assert(buf); /* Only append a semicolon if something's already there */ if (0 != buflen) diff --git a/src/apply_gridshift.cpp b/src/apply_gridshift.cpp index c7070432..d9b5286d 100644 --- a/src/apply_gridshift.cpp +++ b/src/apply_gridshift.cpp @@ -59,7 +59,10 @@ int pj_apply_gridshift( projCtx ctx, const char *nadgrids, int inverse, gridlist = pj_gridlist_from_nadgrids( ctx, nadgrids, &grid_count ); if( gridlist == nullptr || grid_count == 0 ) + { + pj_dalloc( gridlist ); return ctx->last_errno; + } ret = pj_apply_gridshift_3( ctx, gridlist, grid_count, inverse, point_count, point_offset, x, y, z ); diff --git a/src/apply_vgridshift.cpp b/src/apply_vgridshift.cpp index ae23e39a..9be65f08 100644 --- a/src/apply_vgridshift.cpp +++ b/src/apply_vgridshift.cpp @@ -98,10 +98,13 @@ static double read_vgrid_value( PJ *defn, PJ_LP input, double vmultiplier, int * } /* load the grid shift info if we don't have it. */ - if( ct->cvs == nullptr && !pj_gridinfo_load( pj_get_ctx(defn), gi ) ) + if( ct->cvs == nullptr ) { - pj_ctx_set_errno( defn->ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); - return PJD_ERR_FAILED_TO_LOAD_GRID; + if( !pj_gridinfo_load( pj_get_ctx(defn), gi ) || ct->cvs == nullptr ) + { + pj_ctx_set_errno( defn->ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); + return PJD_ERR_FAILED_TO_LOAD_GRID; + } } diff --git a/src/apps/cct.cpp b/src/apps/cct.cpp index 34bf0777..65718aca 100644 --- a/src/apps/cct.cpp +++ b/src/apps/cct.cpp @@ -228,6 +228,7 @@ int main(int argc, char **argv) { fout = stdout; + /* coverity[tainted_data] */ o = opt_parse (argc, argv, "hvI", "cdozts", longflags, longkeys); if (nullptr==o) return 0; @@ -368,6 +369,7 @@ int main(int argc, char **argv) { point.lpzt.phi = proj_torad (point.lpzt.phi); } err = proj_errno_reset (P); + /* coverity[returned_value] */ point = proj_trans (P, direction, point); if (HUGE_VAL==point.xyzt.x) { diff --git a/src/apps/cs2cs.cpp b/src/apps/cs2cs.cpp index 55b38bbc..877a68ff 100644 --- a/src/apps/cs2cs.cpp +++ b/src/apps/cs2cs.cpp @@ -274,13 +274,6 @@ static std::string get_geog_crs_proj_string_from_proj_crs(PJ *src, double &toRadians, bool &isLatFirst) { auto srcType = proj_get_type(src); - if (srcType == PJ_TYPE_BOUND_CRS) { - auto base = proj_get_source_crs(nullptr, src); - assert(base); - proj_destroy(src); - src = base; - srcType = proj_get_type(src); - } if (srcType != PJ_TYPE_PROJECTED_CRS) { return std::string(); } diff --git a/src/apps/emess.cpp b/src/apps/emess.cpp index 52f88aa3..53018ba8 100644 --- a/src/apps/emess.cpp +++ b/src/apps/emess.cpp @@ -30,7 +30,7 @@ emess(int code, const char *fmt, ...) { va_start(args, fmt); /* prefix program name, if given */ - if (fmt != nullptr) + if (emess_dat.Prog_name != nullptr) (void)fprintf(stderr,"%s\n<%s>: ",pj_get_release(), emess_dat.Prog_name); /* print file name and line, if given */ diff --git a/src/apps/gie.cpp b/src/apps/gie.cpp index 5407c0ba..a84e77ab 100644 --- a/src/apps/gie.cpp +++ b/src/apps/gie.cpp @@ -249,6 +249,7 @@ int main (int argc, char **argv) { T.ignore = 5555; /* Error code that will not be issued by proj_create() */ T.use_proj4_init_rules = FALSE; + /* coverity[tainted_data] */ o = opt_parse (argc, argv, "hlvq", "o", longflags, longkeys); if (nullptr==o) return 0; diff --git a/src/apps/optargpm.h b/src/apps/optargpm.h index 035c6f92..e7f4f8e5 100644 --- a/src/apps/optargpm.h +++ b/src/apps/optargpm.h @@ -534,6 +534,7 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, *equals = '='; if (opt_is_flag (o, c)) { fprintf (stderr, "Option \"%s\" takes no arguments\n", crepr); + free (o); return nullptr; } o->optarg[c] = equals + 1; @@ -544,6 +545,7 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, if (!opt_is_flag (o, c)) { if ((argc==i + 1) || ('+'==argv[i+1][0]) || ('-'==argv[i+1][0])) { fprintf (stderr, "Missing argument for option \"%s\"\n", crepr); + free (o); return nullptr; } o->optarg[c] = argv[i + 1]; @@ -553,6 +555,7 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, if (!opt_is_flag (o, c)) { fprintf (stderr, "Expected flag style long option here, but got \"%s\"\n", crepr); + free (o); return nullptr; } @@ -564,6 +567,7 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, /* classic short options */ if (nullptr==o->optarg[c]) { fprintf (stderr, "Invalid option \"%s\"\n", crepr); + free (o); return nullptr; } @@ -580,6 +584,7 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, if ((argc==i + 1) || ('+'==argv[i+1][0]) || ('-'==argv[i+1][0])) { fprintf (stderr, "Bad or missing arg for option \"%s\"\n", crepr); + free (o); return nullptr; } o->optarg[(int) c] = argv[i + 1]; diff --git a/src/apps/proj.cpp b/src/apps/proj.cpp index 5f0ee71f..2af49c34 100644 --- a/src/apps/proj.cpp +++ b/src/apps/proj.cpp @@ -532,7 +532,7 @@ int main(int argc, char **argv) { } else { if ((fid = fopen(*eargv, "rb")) == nullptr) { - emess(-2, *eargv, "input file"); + emess(-2, "input file: %s", *eargv); continue; } emess_dat.File_name = *eargv; diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp index 4c99d7ce..7d4a8399 100644 --- a/src/apps/projinfo.cpp +++ b/src/apps/projinfo.cpp @@ -1132,11 +1132,18 @@ int main(int argc, char **argv) { } } - outputOperations( - dbContext, sourceCRSStr, targetCRSStr, bboxFilter, spatialCriterion, - spatialCriterionExplicitlySpecified, crsExtentUse, - gridAvailabilityUse, allowUseIntermediateCRS, pivots, authority, - usePROJGridAlternatives, showSuperseded, outputOpt, summary); + try { + outputOperations(dbContext, sourceCRSStr, targetCRSStr, bboxFilter, + spatialCriterion, + spatialCriterionExplicitlySpecified, crsExtentUse, + gridAvailabilityUse, allowUseIntermediateCRS, + pivots, authority, usePROJGridAlternatives, + showSuperseded, outputOpt, summary); + } catch (const std::exception &e) { + std::cerr << "outputOperations() failed with: " << e.what() + << std::endl; + std::exit(1); + } } return 0; diff --git a/src/gridcatalog.cpp b/src/gridcatalog.cpp index ca5750ab..15d81dd7 100644 --- a/src/gridcatalog.cpp +++ b/src/gridcatalog.cpp @@ -37,6 +37,13 @@ static PJ_GridCatalog *grid_catalog_list = nullptr; +static +PJ_GRIDINFO *pj_gc_findgrid( projCtx_t *ctx, + PJ_GridCatalog *catalog, int after, + PJ_LP location, double date, + PJ_Region *optional_region, + double *grid_date ); + /************************************************************************/ /* pj_gc_unloadall() */ /* */ @@ -236,6 +243,7 @@ int pj_gc_apply_gridshift( PJ *defn, int inverse, /* pj_c_findgrid() */ /************************************************************************/ +static PJ_GRIDINFO *pj_gc_findgrid( projCtx ctx, PJ_GridCatalog *catalog, int after, PJ_LP location, double date, PJ_Region *optional_region, @@ -287,6 +295,8 @@ PJ_GRIDINFO *pj_gc_findgrid( projCtx ctx, PJ_GridCatalog *catalog, int after, int grid_count = 0; gridlist = pj_gridlist_from_nadgrids( ctx, entry->definition, &grid_count); + // FIXME: this leaks gridlist itself, and memory ownership of + // entry->gridinfo is also confusing. Coverity CID 193539 if( grid_count == 1 ) entry->gridinfo = gridlist[0]; } diff --git a/src/gridinfo.cpp b/src/gridinfo.cpp index 14759557..bff487f5 100644 --- a/src/gridinfo.cpp +++ b/src/gridinfo.cpp @@ -851,7 +851,6 @@ static int pj_gridinfo_init_gtx( projCtx ctx, PAFile fid, PJ_GRIDINFO *gi ) PJ_GRIDINFO *pj_gridinfo_init( projCtx ctx, const char *gridname ) { - char fname[MAX_PATH_FILENAME+1]; PJ_GRIDINFO *gilist; PAFile fp; char header[160]; @@ -885,13 +884,12 @@ PJ_GRIDINFO *pj_gridinfo_init( projCtx ctx, const char *gridname ) /* -------------------------------------------------------------------- */ /* Open the file using the usual search rules. */ /* -------------------------------------------------------------------- */ - strcpy(fname, gridname); - if (!(fp = pj_open_lib(ctx, fname, "rb"))) { + if (!(fp = pj_open_lib(ctx, gridname, "rb"))) { ctx->last_errno = 0; /* don't treat as a persistent error */ return gilist; } - gilist->filename = pj_strdup(fname); + gilist->filename = pj_strdup(gridname); if (!gilist->filename) { pj_dalloc(gilist->gridname); pj_dalloc(gilist); diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index f7dcd354..8e1a60a5 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -975,29 +975,18 @@ int proj_is_equivalent_to(const PJ *obj, const PJ *other, return false; } - // Make sure that the C and C++ enumerations match - static_assert(static_cast<int>(PJ_COMP_STRICT) == - static_cast<int>(IComparable::Criterion::STRICT), - ""); - static_assert(static_cast<int>(PJ_COMP_EQUIVALENT) == - static_cast<int>(IComparable::Criterion::EQUIVALENT), - ""); - static_assert( - static_cast<int>(PJ_COMP_EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS) == - static_cast<int>( - IComparable::Criterion::EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS), - ""); + const auto cppCriterion = ([](PJ_COMPARISON_CRITERION l_criterion) { + switch (l_criterion) { + case PJ_COMP_STRICT: + return IComparable::Criterion::STRICT; + case PJ_COMP_EQUIVALENT: + return IComparable::Criterion::EQUIVALENT; + case PJ_COMP_EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS: + break; + } + return IComparable::Criterion::EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS; + })(criterion); - // Make sure we enumerate all values. If adding a new value, as we - // don't have a default clause, the compiler will warn. - switch (criterion) { - case PJ_COMP_STRICT: - case PJ_COMP_EQUIVALENT: - case PJ_COMP_EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS: - break; - } - const IComparable::Criterion cppCriterion = - static_cast<IComparable::Criterion>(criterion); return obj->iso_obj->isEquivalentTo(other->iso_obj.get(), cppCriterion); } @@ -1121,40 +1110,24 @@ const char *proj_as_wkt(PJ_CONTEXT *ctx, const PJ *obj, PJ_WKT_TYPE type, return nullptr; } - // Make sure that the C and C++ enumerations match - static_assert(static_cast<int>(PJ_WKT2_2015) == - static_cast<int>(WKTFormatter::Convention::WKT2_2015), - ""); - static_assert( - static_cast<int>(PJ_WKT2_2015_SIMPLIFIED) == - static_cast<int>(WKTFormatter::Convention::WKT2_2015_SIMPLIFIED), - ""); - static_assert(static_cast<int>(PJ_WKT2_2018) == - static_cast<int>(WKTFormatter::Convention::WKT2_2018), - ""); - static_assert( - static_cast<int>(PJ_WKT2_2018_SIMPLIFIED) == - static_cast<int>(WKTFormatter::Convention::WKT2_2018_SIMPLIFIED), - ""); - static_assert(static_cast<int>(PJ_WKT1_GDAL) == - static_cast<int>(WKTFormatter::Convention::WKT1_GDAL), - ""); - static_assert(static_cast<int>(PJ_WKT1_ESRI) == - static_cast<int>(WKTFormatter::Convention::WKT1_ESRI), - ""); - // Make sure we enumerate all values. If adding a new value, as we - // don't have a default clause, the compiler will warn. - switch (type) { - case PJ_WKT2_2015: - case PJ_WKT2_2015_SIMPLIFIED: - case PJ_WKT2_2018: - case PJ_WKT2_2018_SIMPLIFIED: - case PJ_WKT1_GDAL: - case PJ_WKT1_ESRI: - break; - } - const WKTFormatter::Convention convention = - static_cast<WKTFormatter::Convention>(type); + const auto convention = ([](PJ_WKT_TYPE l_type) { + switch (l_type) { + case PJ_WKT2_2015: + return WKTFormatter::Convention::WKT2_2015; + case PJ_WKT2_2015_SIMPLIFIED: + return WKTFormatter::Convention::WKT2_2015_SIMPLIFIED; + case PJ_WKT2_2018: + return WKTFormatter::Convention::WKT2_2018; + case PJ_WKT2_2018_SIMPLIFIED: + return WKTFormatter::Convention::WKT2_2018_SIMPLIFIED; + case PJ_WKT1_GDAL: + return WKTFormatter::Convention::WKT1_GDAL; + case PJ_WKT1_ESRI: + break; + } + return WKTFormatter::Convention::WKT1_ESRI; + })(type); + try { auto dbContext = getDBcontextNoException(ctx, __FUNCTION__); auto formatter = WKTFormatter::create(convention, dbContext); diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 50a6a003..1abb74b3 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -7704,7 +7704,7 @@ void SingleOperation::exportTransformationToWKT( formatter->addQuotedString(nameStr()); - if (isWKT2 && formatter->use2018Keywords()) { + if (formatter->use2018Keywords()) { const auto &version = operationVersion(); if (version.has_value()) { formatter->startNode(io::WKTConstants::VERSION, false); @@ -7719,10 +7719,8 @@ void SingleOperation::exportTransformationToWKT( method()->_exportToWKT(formatter); - const MethodMapping *mapping = - !isWKT2 ? getMapping(method().get()) : nullptr; for (const auto ¶mValue : parameterValues()) { - paramValue->_exportToWKT(formatter, mapping); + paramValue->_exportToWKT(formatter, nullptr); } if (!formatter->abridgedTransformation()) { @@ -9163,6 +9161,7 @@ void ConcatenatedOperation::fixStepsDirection( op = op->inverse(); } } else if (i + 1 < operationsInOut.size()) { + /* coverity[copy_paste_error] */ l_targetCRS = operationsInOut[i + 1]->sourceCRS(); if (l_targetCRS) { op->setCRSs(concatOpSourceCRS, NN_NO_CHECK(l_targetCRS), diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index 2dc6b3bf..b51d03c9 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -1892,9 +1892,7 @@ void GeographicCRS::addAngularUnitConvertAndAxisSwap( if (order[0] && order[1] && (order[0] != one || order[1] != two)) { formatter->addStep("axisswap"); char orderStr[10]; - strcpy(orderStr, order[0]); - strcat(orderStr, ","); - strcat(orderStr, order[1]); + sprintf(orderStr, "%.2s,%.2s", order[0], order[1]); formatter->addParam("order", orderStr); } } @@ -2851,9 +2849,7 @@ void ProjectedCRS::addUnitConvertAndAxisSwap(io::PROJStringFormatter *formatter, if (order[0] && order[1]) { formatter->addStep("axisswap"); char orderStr[10]; - strcpy(orderStr, order[0]); - strcat(orderStr, ","); - strcat(orderStr, order[1]); + sprintf(orderStr, "%.2s,%.2s", order[0], order[1]); formatter->addParam("order", orderStr); } } else { diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 14421022..e42ed89f 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -259,7 +259,7 @@ struct DatabaseContext::Private { static void getFromCache(LRUCacheOfObjects &cache, const std::string &code, util::BaseObjectPtr &obj); - void closeDB(); + void closeDB() noexcept; // cppcheck-suppress functionStatic void registerFunctions(); @@ -295,7 +295,7 @@ DatabaseContext::Private::~Private() { // --------------------------------------------------------------------------- -void DatabaseContext::Private::closeDB() { +void DatabaseContext::Private::closeDB() noexcept { if (detach_) { // Workaround a bug visible in SQLite 3.8.1 and 3.8.2 that causes @@ -309,7 +309,10 @@ void DatabaseContext::Private::closeDB() { // https://github.com/mackyle/sqlite/commit/ccf328c4318eacedab9ed08c404bc4f402dcad19 // also seemed to hide the issue. // Detaching a database hides the issue, not sure if it is by chance... - run("DETACH DATABASE db_0"); + try { + run("DETACH DATABASE db_0"); + } catch (...) { + } detach_ = false; } @@ -1615,7 +1618,8 @@ static double normalizeMeasure(const std::string &uom_code, assert(seconds.size() == precision - 2); normalized_value = (normalized_value < 0 ? -1.0 : 1.0) * - (int(std::fabs(normalized_value)) + c_locale_stod(minutes) / 60. + + (std::floor(std::fabs(normalized_value)) + + c_locale_stod(minutes) / 60. + (c_locale_stod(seconds) / std::pow(10, seconds.size() - 2)) / 3600.); normalized_uom_code = common::UnitOfMeasure::DEGREE.code(); diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 578234b4..502f30e6 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -3168,7 +3168,6 @@ ConversionNNPtr WKTParser::Private::buildProjectionFromESRI( } const auto *wkt2_mapping = getMapping(esriMapping->wkt2_name); - assert(wkt2_mapping); if (ci_equal(esriProjectionName, "Stereographic")) { try { if (std::fabs(io::asDouble( @@ -3179,6 +3178,7 @@ ConversionNNPtr WKTParser::Private::buildProjectionFromESRI( } catch (const std::exception &) { } } + assert(wkt2_mapping); PropertyMap propertiesMethod; propertiesMethod.set(IdentifiedObject::NAME_KEY, wkt2_mapping->wkt2_name); @@ -6734,6 +6734,9 @@ static double getNumericValue(const std::string ¶mValue, } // --------------------------------------------------------------------------- +namespace { +template <class T> inline void ignoreRetVal(T) {} +} GeographicCRSNNPtr PROJStringParser::Private::buildGeographicCRS(int iStep, int iUnitConvert, @@ -6746,7 +6749,7 @@ PROJStringParser::Private::buildGeographicCRS(int iStep, int iUnitConvert, // units=m is often found in the wild. // No need to create a extension string for this - hasParamValue(step, "units"); + ignoreRetVal(hasParamValue(step, "units")); auto datum = buildDatum(step, title); diff --git a/src/nad_init.cpp b/src/nad_init.cpp index d9701e70..315318be 100644 --- a/src/nad_init.cpp +++ b/src/nad_init.cpp @@ -265,7 +265,6 @@ struct CTABLE *nad_ctable2_init( projCtx ctx, struct projFileAPI_t* fileapi ) struct CTABLE *nad_init(projCtx ctx, char *name) { - char fname[MAX_PATH_FILENAME+1]; struct CTABLE *ct; PAFile fid; @@ -274,8 +273,7 @@ struct CTABLE *nad_init(projCtx ctx, char *name) /* -------------------------------------------------------------------- */ /* Open the file using the usual search rules. */ /* -------------------------------------------------------------------- */ - strcpy(fname, name); - if (!(fid = pj_open_lib(ctx, fname, "rb"))) { + if (!(fid = pj_open_lib(ctx, name, "rb"))) { return nullptr; } diff --git a/src/proj_internal.h b/src/proj_internal.h index cdde6bad..880e194f 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -898,12 +898,6 @@ int pj_gc_apply_gridshift( PJ *defn, int inverse, long point_count, int point_offset, double *x, double *y, double *z ); -PJ_GRIDINFO *pj_gc_findgrid( projCtx_t *ctx, - PJ_GridCatalog *catalog, int after, - PJ_LP location, double date, - PJ_Region *optional_region, - double *grid_date ); - double pj_gc_parsedate( projCtx_t *, const char * ); void *proj_mdist_ini(double); |
