diff --git a/CMakeLists.txt b/CMakeLists.txt index 46f9040d..c9def1af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ cmake_minimum_required( VERSION 3.12 FATAL_ERROR ) find_package( ecbuild 3.7.2 REQUIRED HINTS ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../ecbuild) -project( metkit LANGUAGES CXX ) +project( metkit LANGUAGES CXX C ) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/src/metkit/CMakeLists.txt b/src/metkit/CMakeLists.txt index 5303e8b5..766e4548 100644 --- a/src/metkit/CMakeLists.txt +++ b/src/metkit/CMakeLists.txt @@ -4,6 +4,7 @@ ecbuild_generate_config_headers( DESTINATION ${INSTALL_INCLUDE_DIR}/metkit ) configure_file( metkit_config.h.in metkit_config.h ) configure_file( metkit_version.h.in metkit_version.h ) +configure_file( metkit_version.c.in ${CMAKE_CURRENT_BINARY_DIR}/metkit_version.c ) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/metkit_config.h @@ -14,6 +15,7 @@ install(FILES ### metkit sources list( APPEND metkit_srcs + ${CMAKE_CURRENT_BINARY_DIR}/metkit_version.c config/LibMetkit.cc config/LibMetkit.h mars/BaseProtocol.cc diff --git a/src/metkit/api/metkit_c.cc b/src/metkit/api/metkit_c.cc index b792bd7b..e1390990 100644 --- a/src/metkit/api/metkit_c.cc +++ b/src/metkit/api/metkit_c.cc @@ -37,33 +37,6 @@ struct metkit_requestiterator_t { std::vector::iterator iterator_; }; -/// @comment: (maby) -/// Not sure if there is much value in having a param iterator. We could just return an array of -/// strings (char**) using metkit_marsrequest_params. -/// I think we should metkit_paramiterator_t. -struct metkit_paramiterator_t { - explicit metkit_paramiterator_t(std::vector vec) : - vector_(std::move(vec)), iterator_(vector_.begin()) {} - - int next() { - if (iterator_ == vector_.end()) { - return METKIT_ITERATION_COMPLETE; - } - ++iterator_; - - return iterator_ == vector_.end() ? METKIT_ITERATION_COMPLETE : METKIT_SUCCESS; - } - - void current(const char** param) { - ASSERT(iterator_ != vector_.end()); - *param = iterator_->c_str(); - } - -private: - std::vector vector_; - std::vector::iterator iterator_; -}; - // --------------------------------------------------------------------------------------------------------------------- // ERROR HANDLING @@ -99,27 +72,22 @@ template return innerWrapFn(fn); } catch (const eckit::UserError& e) { - eckit::Log::error() << "User Error: " << e.what() << std::endl; g_current_error_string = e.what(); return METKIT_ERROR_USER; } catch (const eckit::AssertionFailed& e) { - eckit::Log::error() << "Assertion Failed: " << e.what() << std::endl; g_current_error_string = e.what(); return METKIT_ERROR_ASSERT; } catch (const eckit::Exception& e) { - eckit::Log::error() << "METKIT Error: " << e.what() << std::endl; g_current_error_string = e.what(); return METKIT_ERROR; } catch (const std::exception& e) { - eckit::Log::error() << "Unknown Error: " << e.what() << std::endl; g_current_error_string = e.what(); return METKIT_ERROR_UNKNOWN; } catch (...) { - eckit::Log::error() << "Unknown Error!" << std::endl; return METKIT_ERROR_UNKNOWN; } } @@ -128,16 +96,6 @@ template // HELPERS // ----------------------------------------------------------------------------- -int metkit_version(const char** version) { - *version = metkit_version_str(); - return METKIT_SUCCESS; -} - -int metkit_vcs_version(const char** sha1) { - *sha1 = metkit_git_sha1(); - return METKIT_SUCCESS; -} - int metkit_initialise() { return tryCatch([] { static bool initialised = false; @@ -159,7 +117,7 @@ int metkit_initialise() { // PARSING // ----------------------------------------------------------------------------- -int metkit_parse_marsrequest(const char* str, metkit_requestiterator_t** requests, bool strict) { +int metkit_parse_marsrequests(const char* str, metkit_requestiterator_t** requests, bool strict) { return tryCatch([requests, str, strict] { ASSERT(requests); ASSERT(str); @@ -198,7 +156,7 @@ int metkit_marsrequest_set(metkit_marsrequest_t* request, const char* param, con request->values(param_str, values_vec); }); } - + int metkit_marsrequest_set_one(metkit_marsrequest_t* request, const char* param, const char* value) { return metkit_marsrequest_set(request, param, &value, 1); } @@ -228,11 +186,19 @@ int metkit_marsrequest_has_param(const metkit_marsrequest_t* request, const char }); } -int metkit_marsrequest_params(const metkit_marsrequest_t* request, metkit_paramiterator_t** params) { - return tryCatch([request, params] { +int metkit_marsrequest_count_params(const metkit_marsrequest_t* request, size_t* count) { + return tryCatch([request, count] { ASSERT(request); - ASSERT(params); - *params = new metkit_paramiterator_t(request->params()); + ASSERT(count); + *count = request->params().size(); + }); +} + +int metkit_marsrequest_param(const metkit_marsrequest_t* request, size_t index, const char** param) { + return tryCatch([request, index, param] { + ASSERT(request); + ASSERT(param); + *param = request->params()[index].c_str(); }); } @@ -250,24 +216,10 @@ int metkit_marsrequest_value(const metkit_marsrequest_t* request, const char* pa ASSERT(request); ASSERT(param); ASSERT(value); - *value = (request->values(param, false))[index].c_str(); + *value = request->values(param, false)[index].c_str(); }); } - -int metkit_marsrequest_values(const metkit_marsrequest_t* request, const char* param, const char** values[], size_t* numValues) { - return tryCatch([request, param, values, numValues] { - ASSERT(request); - ASSERT(param); - ASSERT(values); - ASSERT(numValues); - const std::vector& values_str = request->values(param); - *numValues = values_str.size(); - *values = new const char*[values_str.size()]; - std::transform(values_str.begin(), values_str.end(), *values, [](const std::string& s) { return s.c_str(); }); - }); -} - -int metkit_marsrequest_expand(const metkit_marsrequest_t* request, metkit_marsrequest_t* expandedRequest, bool inherit, bool strict) { +int metkit_marsrequest_expand(const metkit_marsrequest_t* request, bool inherit, bool strict, metkit_marsrequest_t* expandedRequest) { return tryCatch([request, expandedRequest, inherit, strict] { ASSERT(request); ASSERT(expandedRequest); @@ -312,30 +264,4 @@ int metkit_requestiterator_request(metkit_requestiterator_t* it, metkit_marsrequ }); } -// ----------------------------------------------------------------------------- -// PARAM ITERATOR -// ----------------------------------------------------------------------------- - -int metkit_delete_paramiterator(const metkit_paramiterator_t* it) { - return tryCatch([it] { - delete it; - }); -} - -int metkit_paramiterator_next(metkit_paramiterator_t* it) { - return tryCatch(std::function{[it] { - ASSERT(it); - return it->next(); - }}); -} - -int metkit_paramiterator_param(metkit_paramiterator_t* it, const char** param) { - return tryCatch([it, param] { - ASSERT(it); - ASSERT(param); - it->current(param); - }); -} - - // --------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/metkit/api/metkit_c.h b/src/metkit/api/metkit_c.h index edcde0a4..40b29554 100644 --- a/src/metkit/api/metkit_c.h +++ b/src/metkit/api/metkit_c.h @@ -43,20 +43,18 @@ const char* metkit_get_error_string(enum metkit_error_values_t err); * ------- */ /** - * @brief Set MetKit version. + * @brief Get metkit version. * - * @param version Version string - * @return int Error code + * @return const char* version string */ -int metkit_version(const char** version); +const char* metkit_version(); /** - * @brief Set MetKit git sha1 version. + * @brief Get metkit git sha1 version. * - * @param sha1 SHA1 version string - * @return int Error code + * @return const char* git sha1 version string */ -int metkit_vcs_version(const char** sha1); +const char* metkit_git_sha1(); /** * @brief Initialise Main() context. @@ -75,17 +73,17 @@ int metkit_initialise(); * Parse MARS requests into RequestIterator of Request instances. Resulting RequestIterator * must be deallocated with metkit_delete_requestiterator * @param str MARS requests - * @param requests Allocates RequestIterator object + * @param[out] requests Allocates RequestIterator object * @return int Error code */ -int metkit_parse_marsrequest(const char* str, metkit_requestiterator_t** requests, bool strict); +int metkit_parse_marsrequests(const char* str, metkit_requestiterator_t** requests, bool strict); /* --------------------------------------------------------------------------------------------------------------------- * REQUEST * --- */ /** Allocates new Request object. Must be deallocated with mekit_delete_request - * @param request new Request instance + * @param[out] request new Request instance * @return int Error code */ int metkit_new_marsrequest(metkit_marsrequest_t** request); @@ -122,7 +120,7 @@ int metkit_marsrequest_set_verb(metkit_marsrequest_t* request, const char* verb) /** Returns the verb in Request object * @param request Request instance - * @param verb verb in request + * @param[out] verb verb in request * @return int Error code */ int metkit_marsrequest_verb(const metkit_marsrequest_t* request, const char** verb); @@ -130,23 +128,32 @@ int metkit_marsrequest_verb(const metkit_marsrequest_t* request, const char** ve /** Returns whether parameter is in Request object * @param request Request instance * @param param parameter name - * @param has whether parameter exists in request + * @param[out] has whether parameter exists in request * @return int Error code */ int metkit_marsrequest_has_param(const metkit_marsrequest_t* request, const char* param, bool* has); -/** Returns ParamIterator of parameters in request. Resulting ParamIterator - * must be deallocated with metkit_delete_paramiterator + +/** Returns number of parameters in Request object + * @param request Request instance + * @param[out] count number of parameters in request + * @return int Error code + */ +int metkit_marsrequest_count_params(const metkit_marsrequest_t* request, size_t* count); + +/** Returns parameter name for specific index in Request object * @param request Request instance - * @param params Allocates ParamIterator object for parameter names in request + * @param index index of parameter to retrieve + * @param[out] param parameter name * @return int Error code */ -int metkit_marsrequest_params(const metkit_marsrequest_t* request, metkit_paramiterator_t** params); +int metkit_marsrequest_param(const metkit_marsrequest_t* request, size_t index, const char** param); + /** Returns number of values for specific parameter in Request object * @param request Request instance * @param param parameter name in request - * @param count number of values for param in request + * @param[out] count number of values for param in request * @return int Error code */ int metkit_marsrequest_count_values(const metkit_marsrequest_t* request, const char* param, size_t* count); @@ -155,28 +162,19 @@ int metkit_marsrequest_count_values(const metkit_marsrequest_t* request, const c * @param request Request instance * @param param parameter name in request * @param index index of value to retrieve for param in request - * @param value retrieved value + * @param[out] value retrieved value * @return int Error code */ int metkit_marsrequest_value(const metkit_marsrequest_t* request, const char* param, int index, const char** value); -/** Returns values for specific parameter Request object - * @param request Request instance - * @param param parameter name in request - * @param values array of values for param in request - * @param numValues number of values for param in request - * @return int Error code - */ -int metkit_marsrequest_values(const metkit_marsrequest_t* request, const char* param, const char** values[], size_t* numValues); - /** Populates empty Request object by expanding existing request * @param request Request instance to be expanded - * @param expandedRequest empty Request instance to be populated * @param inherit if true, populate expanded request with default values * @param strict it true, raise error rather than warning on invalid values + * @param[out] expandedRequest empty Request instance to be populated * @return int Error code */ -int metkit_marsrequest_expand(const metkit_marsrequest_t* request, metkit_marsrequest_t* expandedRequest, bool inherit, bool strict); +int metkit_marsrequest_expand(const metkit_marsrequest_t* request, bool inherit, bool strict, metkit_marsrequest_t* expandedRequest); /** Merges other Request object into existing request * @param request Request instance to contain result of merge @@ -208,29 +206,6 @@ int metkit_requestiterator_next(metkit_requestiterator_t* it); */ int metkit_requestiterator_request(metkit_requestiterator_t* it, metkit_marsrequest_t* request); -/* --------------------------------------------------------------------------------------------------------------------- - * PARAM ITERATOR - * --- */ - -/** Deallocates ParamIterator object and associated resources. - * @param it ParamIterator instance - * @return int Error code - */ -int metkit_delete_paramiterator(const metkit_paramiterator_t* it); - -/** Moves to the next string element in ParamIterator - * @param it ParamIterator instance - * @return int Error code - */ -int metkit_paramiterator_next(metkit_paramiterator_t* it); - -/** Returns the current parameter name in ParamIterator - * @param it ParamIterator instance - * @param param current parameter name in iterator - * @return int Error code - */ -int metkit_paramiterator_param(metkit_paramiterator_t* it, const char** param); - #ifdef __cplusplus } #endif diff --git a/src/metkit/metkit_version.c.in b/src/metkit/metkit_version.c.in new file mode 100644 index 00000000..13b34cde --- /dev/null +++ b/src/metkit/metkit_version.c.in @@ -0,0 +1,19 @@ +#include "metkit_version.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const char * metkit_version() { return metkit_VERSION; } + +unsigned int metkit_version_int() { + return 10000*metkit_VERSION_MAJOR + 100*metkit_VERSION_MINOR + 1*metkit_VERSION_PATCH; +} + +const char * metkit_version_str() { return metkit_VERSION_STR; } + +const char * metkit_git_sha1() { return "@metkit_GIT_SHA1@"; } + +#ifdef __cplusplus +} +#endif diff --git a/src/metkit/metkit_version.h.in b/src/metkit/metkit_version.h.in index 658a5be7..8d5d65b9 100644 --- a/src/metkit/metkit_version.h.in +++ b/src/metkit/metkit_version.h.in @@ -8,14 +8,22 @@ #define metkit_VERSION_MINOR @metkit_VERSION_MINOR@ #define metkit_VERSION_PATCH @metkit_VERSION_PATCH@ -inline const char * metkit_version() { return metkit_VERSION; } -inline unsigned int metkit_version_int() { - return 10000*metkit_VERSION_MAJOR + 100*metkit_VERSION_MINOR + 1*metkit_VERSION_PATCH; -} +#ifdef __cplusplus +extern "C" { +#endif + +const char * metkit_version(); + +unsigned int metkit_version_int(); -inline const char * metkit_version_str() { return metkit_VERSION_STR; } +const char * metkit_version_str(); + +const char * metkit_git_sha1(); + +#ifdef __cplusplus +} +#endif -inline const char * metkit_git_sha1() { return "@metkit_GIT_SHA1@"; } #endif // metkit_version_h diff --git a/tests/test_c_api.c b/tests/test_c_api.c index 977a965a..9ba93750 100644 --- a/tests/test_c_api.c +++ b/tests/test_c_api.c @@ -17,8 +17,7 @@ int main(int argc, char **argv) { - const char* version; - int errno = metkit_version(&version); + const char* version = metkit_version(); fprintf(stdout, "MetKit version: %s\n", version); diff --git a/tests/test_c_api.cc b/tests/test_c_api.cc index fa3e58b7..992aa571 100644 --- a/tests/test_c_api.cc +++ b/tests/test_c_api.cc @@ -79,28 +79,22 @@ CASE( "metkit_marsrequest" ) { EXPECT_STR_EQUAL(value, dates[i]); } - // all values - const char** values{}; - count = 0; - METKIT_TEST_C(metkit_marsrequest_values(request, "date", &values, &count)); - EXPECT_EQUAL(count, 3); - - for (size_t i = 0; i < count; i++) { - EXPECT_STR_EQUAL(values[i], dates[i]); - } - // ----------------------------------------------------------------- // Expand // ----------------------------------------------------------------- metkit_marsrequest_t* expandedRequest{}; METKIT_TEST_C(metkit_new_marsrequest(&expandedRequest)); - METKIT_TEST_C(metkit_marsrequest_expand(request, expandedRequest, false, true)); + METKIT_TEST_C(metkit_marsrequest_expand(request, false, true, expandedRequest)); // Check date expanded -1 -> yesterday - const char** dates_expanded{}; - METKIT_TEST_C(metkit_marsrequest_values(expandedRequest, "date", &dates_expanded, &count)); + METKIT_TEST_C(metkit_marsrequest_count_values(expandedRequest, "date", &count)); EXPECT_EQUAL(count, 3); + const char** dates_expanded = new const char*[count]; + for (size_t i = 0; i < count; i++) { + METKIT_TEST_C(metkit_marsrequest_value(expandedRequest, "date", i, &dates_expanded[i])); + } + EXPECT_STR_EQUAL(dates_expanded[2], std::to_string(eckit::Date(-1).yyyymmdd()).c_str()); // check param expanded 2t -> 167 const char* param{}; @@ -139,7 +133,7 @@ CASE( "metkit_requestiterator_t parsing" ) { METKIT_TEST_C(metkit_new_marsrequest(&request2)); metkit_requestiterator_t* it{}; - METKIT_TEST_C(metkit_parse_marsrequest("retrieve,date=-1,param=2t \n retrieve,date=20200102,param=2t,step=10/to/20/by/2", &it, true)); // two requests + METKIT_TEST_C(metkit_parse_marsrequests("retrieve,date=-1,param=2t \n retrieve,date=20200102,param=2t,step=10/to/20/by/2", &it, true)); // two requests METKIT_TEST_C(metkit_requestiterator_request(it, request0)); METKIT_TEST_C(metkit_requestiterator_next(it)); @@ -157,11 +151,13 @@ CASE( "metkit_requestiterator_t parsing" ) { EXPECT_STR_EQUAL(date, "20200102"); // Check steps have been parsed - const char** steps{}; size_t count = 0; - METKIT_TEST_C(metkit_marsrequest_values(request1, "step", &steps, &count)); + METKIT_TEST_C(metkit_marsrequest_count_values(request1, "step", &count)); + EXPECT_EQUAL(count, 6); for (size_t i = 0; i < count; i++) { - EXPECT_STR_EQUAL(steps[i], std::to_string(10 + i*2).c_str()); + const char* step{}; + METKIT_TEST_C(metkit_marsrequest_value(request1, "step", i, &step)); + EXPECT_STR_EQUAL(step, std::to_string(10 + i*2).c_str()); } }