From 3d7bae58c4b9b128e6000a2fe1fe65595235bb14 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 6 Jul 2016 15:24:26 +0000 Subject: [PATCH] misc fixes --- src/arm/gnunet-service-arm.c | 22 +++--- src/ats-tests/ats-testing-log.c | 2 +- src/ats-tests/gnunet-ats-sim.c | 77 +++++++++++-------- src/ats-tests/perf_ats.c | 8 +- src/ats/ats_api_scheduling.c | 1 + src/conversation/conversation.h | 8 ++ src/conversation/conversation_api.c | 2 +- .../gnunet-service-conversation.c | 4 +- src/datastore/gnunet-service-datastore.c | 39 +++++++--- src/datastore/plugin_datastore_mysql.c | 1 + src/gnsrecord/plugin_gnsrecord_dns.c | 5 +- src/nse/perf_kdf.c | 4 +- src/regex/regex_internal.c | 4 +- src/set/gnunet-service-set_union.c | 5 +- src/testbed-logger/testbed_logger_api.c | 2 +- src/testbed/gnunet-daemon-testbed-blacklist.c | 3 +- src/util/test_container_multihashmap.c | 6 +- src/util/test_container_multipeermap.c | 6 +- 18 files changed, 116 insertions(+), 83 deletions(-) diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c index 8bc6e9e07..4c60897e5 100644 --- a/src/arm/gnunet-service-arm.c +++ b/src/arm/gnunet-service-arm.c @@ -464,17 +464,17 @@ start_process (struct ServiceList *sl, fin_options = GNUNET_strdup (final_option); /* replace '{}' with service name */ while (NULL != (optpos = strstr (fin_options, "{}"))) - { - /* terminate string at opening parenthesis */ - *optpos = 0; - GNUNET_asprintf (&new_options, - "%s%s%s", - fin_options, - sl->name, - optpos + 2); - GNUNET_free (fin_options); - fin_options = new_options; - } + { + /* terminate string at opening parenthesis */ + *optpos = 0; + GNUNET_asprintf (&new_options, + "%s%s%s", + fin_options, + sl->name, + optpos + 2); + GNUNET_free (fin_options); + fin_options = new_options; + } if (NULL != options) { /* combine "fin_options" with "options" */ diff --git a/src/ats-tests/ats-testing-log.c b/src/ats-tests/ats-testing-log.c index 61aca6b18..6e8e3bd13 100644 --- a/src/ats-tests/ats-testing-log.c +++ b/src/ats-tests/ats-testing-log.c @@ -693,7 +693,7 @@ GNUNET_ATS_TEST_logging_now (struct LoggingHandle *l) else { mlt->total_throughput_send = mult * mlt->total_bytes_sent; - mlt->total_throughput_send = mult * mlt->total_bytes_received; + mlt->total_throughput_recv = mult * mlt->total_bytes_received; } if (GNUNET_YES == l->verbose) diff --git a/src/ats-tests/gnunet-ats-sim.c b/src/ats-tests/gnunet-ats-sim.c index 27850e3e7..f624c2b21 100644 --- a/src/ats-tests/gnunet-ats-sim.c +++ b/src/ats-tests/gnunet-ats-sim.c @@ -57,10 +57,12 @@ static int opt_plot; */ static int opt_verbose; -struct GNUNET_SCHEDULER_Task * timeout_task; +static struct GNUNET_SCHEDULER_Task *timeout_task; + +static struct Experiment *e; + +static struct LoggingHandle *l; -struct Experiment *e; -struct LoggingHandle *l; static void evaluate (struct GNUNET_TIME_Relative duration_total) @@ -125,11 +127,16 @@ evaluate (struct GNUNET_TIME_Relative duration_total) } } + static void -do_shutdown () +do_shutdown (void *cls) { fprintf (stderr, "Shutdown\n"); - /* timeout */ + if (NULL != timeout_task) + { + GNUNET_SCHEDULER_cancel (timeout_task); + timeout_task = NULL; + } if (NULL != l) { GNUNET_ATS_TEST_logging_stop (l); @@ -152,10 +159,18 @@ do_shutdown () } +static void +do_timeout (void *cls) +{ + timeout_task = NULL; + GNUNET_SCHEDULER_shutdown (); +} + + static void transport_recv_cb (void *cls, - const struct GNUNET_PeerIdentity * peer, - const struct GNUNET_MessageHeader * message) + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MessageHeader *message) { } @@ -175,19 +190,19 @@ log_request__cb (void *cls, const struct GNUNET_HELLO_Address *address, } + static void -experiment_done_cb (struct Experiment *e, struct GNUNET_TIME_Relative duration,int success) +experiment_done_cb (struct Experiment *e, + struct GNUNET_TIME_Relative duration,int success) { if (GNUNET_OK == success) - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment done successful in %s\n", - GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES)); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Experiment done successful in %s\n", + GNUNET_STRINGS_relative_time_to_string (duration, + GNUNET_YES)); else GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment failed \n"); - if (NULL != timeout_task) - { - GNUNET_SCHEDULER_cancel (timeout_task); - timeout_task = NULL; - } + /* Stop logging */ GNUNET_ATS_TEST_logging_stop (l); @@ -200,31 +215,20 @@ experiment_done_cb (struct Experiment *e, struct GNUNET_TIME_Relative duration,i evaluate (duration); if (opt_log) GNUNET_ATS_TEST_logging_write_to_file(l, opt_exp_file, opt_plot); - - if (NULL != l) - { - GNUNET_ATS_TEST_logging_stop (l); - GNUNET_ATS_TEST_logging_clean_up (l); - l = NULL; - } - - /* Clean up experiment */ - GNUNET_ATS_TEST_experimentation_stop (e); - e = NULL; - - /* Shutdown topology */ - GNUNET_ATS_TEST_shutdown_topology (); + GNUNET_SCHEDULER_shutdown (); } + static void episode_done_cb (struct Episode *ep) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Episode %u done\n", ep->id); } + static void topology_setup_done (void *cls, - struct BenchmarkPeer *masters, - struct BenchmarkPeer *slaves) + struct BenchmarkPeer *masters, + struct BenchmarkPeer *slaves) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Topology setup complete!\n"); @@ -309,10 +313,15 @@ static void topology_setup_done (void *cls, } #endif - timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_add (GNUNET_TIME_UNIT_MINUTES, - e->max_duration), &do_shutdown, NULL); + timeout_task + = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_add (GNUNET_TIME_UNIT_MINUTES, + e->max_duration), + &do_timeout, + NULL); + GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); } + static void parse_args (int argc, char *argv[]) { @@ -325,6 +334,7 @@ parse_args (int argc, char *argv[]) { if ((c < (argc - 1)) && (0 == strcmp (argv[c], "-e"))) { + GNUNET_free_non_null (opt_exp_file); opt_exp_file = GNUNET_strdup ( argv[c + 1]); } if (0 == strcmp (argv[c], "-l")) @@ -342,6 +352,7 @@ parse_args (int argc, char *argv[]) } } + int main (int argc, char *argv[]) { diff --git a/src/ats-tests/perf_ats.c b/src/ats-tests/perf_ats.c index 0e4056a6c..a7c1dc3bf 100644 --- a/src/ats-tests/perf_ats.c +++ b/src/ats-tests/perf_ats.c @@ -137,14 +137,12 @@ evaluate () double kb_recv_percent; unsigned int rtt; - duration = (perf_duration.rel_value_us / (1000 * 1000)); + duration = 1 + (perf_duration.rel_value_us / (1000 * 1000)); for (c_m = 0; c_m < num_masters; c_m++) { mp = &mps[c_m]; - if (NULL == mp) - continue; fprintf (stderr, - _("Master [%u]: sent: %u KiB in %u sec. = %u KiB/s, received: %u KiB in %u sec. = %u KiB/s\n"), + "Master [%u]: sent: %u KiB in %u sec. = %u KiB/s, received: %u KiB in %u sec. = %u KiB/s\n", mp->no, mp->total_bytes_sent / 1024, duration, (mp->total_bytes_sent / 1024) / duration, mp->total_bytes_received / 1024, duration, @@ -153,8 +151,6 @@ evaluate () for (c_s = 0; c_s < num_slaves; c_s++) { p = &mp->partners[c_s]; - if (NULL == p) - continue; kb_sent_sec = 0; kb_recv_sec = 0; kb_sent_percent = 0.0; diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c index bcca89456..669e2db71 100644 --- a/src/ats/ats_api_scheduling.c +++ b/src/ats/ats_api_scheduling.c @@ -253,6 +253,7 @@ find_empty_session_slot (struct GNUNET_ATS_SchedulingHandle *sh) static uint32_t off; uint32_t i; + GNUNET_assert (0 != sh->session_array_size); i = 0; while ( ( (NOT_FOUND == off) || (NULL != sh->session_array[off % sh->session_array_size]) ) && diff --git a/src/conversation/conversation.h b/src/conversation/conversation.h index aaeed1df3..1bd358e78 100644 --- a/src/conversation/conversation.h +++ b/src/conversation/conversation.h @@ -39,6 +39,14 @@ extern "C" #define MAX_TRANSMIT_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) +/** + * Highest bit in a 32-bit unsigned integer, + * bit set if we are making an outgoing call, + * bit unset for local lines. + */ +#define HIGH_BIT ((uint32_t) (1LL << 31)) + + /** * Message to transmit the audio (between client and helpers). */ diff --git a/src/conversation/conversation_api.c b/src/conversation/conversation_api.c index 730cf1c70..e3bab295e 100644 --- a/src/conversation/conversation_api.c +++ b/src/conversation/conversation_api.c @@ -609,7 +609,7 @@ GNUNET_CONVERSATION_phone_create (const struct GNUNET_CONFIGURATION_Handle *cfg, "LINE"); return NULL; } - if (line >= (1 << 31)) + if (line >= HIGH_BIT) { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "CONVERSATION", diff --git a/src/conversation/gnunet-service-conversation.c b/src/conversation/gnunet-service-conversation.c index 425f0a3c2..3b2237229 100644 --- a/src/conversation/gnunet-service-conversation.c +++ b/src/conversation/gnunet-service-conversation.c @@ -285,7 +285,7 @@ handle_client_register_message (void *cls, GNUNET_CONTAINER_DLL_insert (lines_head, lines_tail, line); - line->local_line = ntohl (msg->line) & (~ (1 << 31)); + line->local_line = ntohl (msg->line) & (~ HIGH_BIT); GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -703,7 +703,7 @@ handle_client_call_message (void *cls, } line = GNUNET_new (struct Line); line->client = client; - line->local_line = (local_line_cnt++) | (1 << 31); + line->local_line = (local_line_cnt++) | HIGH_BIT; GNUNET_SERVER_client_set_user_context (client, line); GNUNET_SERVER_notification_context_add (nc, client); GNUNET_CONTAINER_DLL_insert (lines_head, diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c index 8f4df3ba7..898b6a9d8 100644 --- a/src/datastore/gnunet-service-datastore.c +++ b/src/datastore/gnunet-service-datastore.c @@ -36,6 +36,11 @@ */ #define MAX_PENDING 1024 +/** + * Limit size of bloom filter to 2 GB. + */ +#define MAX_BF_SIZE ((uint32_t) (1LL << 31)) + /** * How long are we at most keeping "expired" content * past the expiration date in the database? @@ -184,7 +189,7 @@ static unsigned long long payload; * Identity of the task that is used to delete * expired content. */ -static struct GNUNET_SCHEDULER_Task * expired_kill_task; +static struct GNUNET_SCHEDULER_Task *expired_kill_task; /** * Minimum time that content should have to not be discarded instantly @@ -537,7 +542,8 @@ transmit_callback (void *cls, size_t size, void *buf) * @param msg message to transmit, will be freed! */ static void -transmit (struct GNUNET_SERVER_Client *client, struct GNUNET_MessageHeader *msg) +transmit (struct GNUNET_SERVER_Client *client, + struct GNUNET_MessageHeader *msg) { struct TransmitCallbackContext *tcc; @@ -611,14 +617,18 @@ transmit_status (struct GNUNET_SERVER_Client *client, int code, const char *msg) * @param expiration expiration time for the content * @param uid unique identifier for the datum; * maybe 0 if no unique identifier is available - * - * @return GNUNET_SYSERR to abort the iteration, GNUNET_OK to continue, - * GNUNET_NO to delete the item and continue (if supported) + * @return #GNUNET_SYSERR to abort the iteration, #GNUNET_OK to continue, + * #GNUNET_NO to delete the item and continue (if supported) */ static int -transmit_item (void *cls, const struct GNUNET_HashCode * key, uint32_t size, - const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, - uint32_t anonymity, struct GNUNET_TIME_Absolute expiration, +transmit_item (void *cls, + const struct GNUNET_HashCode *key, + uint32_t size, + const void *data, + enum GNUNET_BLOCK_Type type, + uint32_t priority, + uint32_t anonymity, + struct GNUNET_TIME_Absolute expiration, uint64_t uid) { struct GNUNET_SERVER_Client *client = cls; @@ -1798,12 +1808,17 @@ run (void *cls, return; } stats = GNUNET_STATISTICS_create ("datastore", cfg); - GNUNET_STATISTICS_set (stats, gettext_noop ("# quota"), quota, GNUNET_NO); + GNUNET_STATISTICS_set (stats, + gettext_noop ("# quota"), + quota, + GNUNET_NO); cache_size = quota / 8; /* Or should we make this an option? */ - GNUNET_STATISTICS_set (stats, gettext_noop ("# cache size"), cache_size, + GNUNET_STATISTICS_set (stats, + gettext_noop ("# cache size"), + cache_size, GNUNET_NO); - if (quota / (32 * 1024LL) > (1 << 31)) - bf_size = (1 << 31); /* absolute limit: ~2 GB, beyond that BF just won't help anyway */ + if (quota / (32 * 1024LL) > MAX_BF_SIZE) + bf_size = MAX_BF_SIZE; else bf_size = quota / (32 * 1024LL); /* 8 bit per entry, 1 bit per 32 kb in DB */ fn = NULL; diff --git a/src/datastore/plugin_datastore_mysql.c b/src/datastore/plugin_datastore_mysql.c index 0ae5c1a2e..d76b4ccb4 100644 --- a/src/datastore/plugin_datastore_mysql.c +++ b/src/datastore/plugin_datastore_mysql.c @@ -990,6 +990,7 @@ mysql_plugin_get_keys (void *cls, proc (proc_cls, NULL, 0); return; } + memset (&last, 0, sizeof (last)); /* make static analysis happy */ ret = GNUNET_YES; cnt = 0; while (ret == GNUNET_YES) diff --git a/src/gnsrecord/plugin_gnsrecord_dns.c b/src/gnsrecord/plugin_gnsrecord_dns.c index 09125b9d5..aa64f0dd6 100644 --- a/src/gnsrecord/plugin_gnsrecord_dns.c +++ b/src/gnsrecord/plugin_gnsrecord_dns.c @@ -265,7 +265,7 @@ dns_value_to_string (void *cls, * @return the value, 0 if not found */ static unsigned int -rfc4394_mnemonic_to_value (const char *mnemonic) +rfc4398_mnemonic_to_value (const char *mnemonic) { static struct { const char *mnemonic; @@ -425,7 +425,7 @@ dns_string_to_value (void *cls, sdup = GNUNET_strdup (s); typep = strtok (sdup, " "); if ( (NULL == typep) || - ( (0 == (type = rfc4394_mnemonic_to_value (typep))) && + ( (0 == (type = rfc4398_mnemonic_to_value (typep))) && ( (1 != SSCANF (typep, "%u", &type)) || @@ -444,6 +444,7 @@ dns_string_to_value (void *cls, GNUNET_free (sdup); return GNUNET_SYSERR; } + alg = 0; algp = strtok (NULL, " "); if ( (NULL == algp) || ( (0 == (type = rfc4034_mnemonic_to_value (typep))) && diff --git a/src/nse/perf_kdf.c b/src/nse/perf_kdf.c index 4981eae5d..61e477874 100644 --- a/src/nse/perf_kdf.c +++ b/src/nse/perf_kdf.c @@ -76,9 +76,9 @@ main (int argc, char *argv[]) GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES)); GAUGER ("NSE", "Proof-of-work hashing", - 1024LL / (1LL + + 1024.0 / (1.0 + GNUNET_TIME_absolute_get_duration - (start).rel_value_us / 1000LL), "hashes/ms"); + (start).rel_value_us / 1000.0), "hashes/ms"); return 0; } diff --git a/src/regex/regex_internal.c b/src/regex/regex_internal.c index cb78545b9..1d39efca1 100644 --- a/src/regex/regex_internal.c +++ b/src/regex/regex_internal.c @@ -2010,7 +2010,7 @@ dfa_merge_nondistinguishable_states (struct REGEX_INTERNAL_Context *ctx, if ( (s1->accepting && !s2->accepting) || (!s1->accepting && s2->accepting) ) { - idx = s1->marked * state_cnt + s2->marked; + idx = (unsigned long long) s1->marked * state_cnt + s2->marked; table[idx / 32] |= (1 << (idx % 32)); } @@ -2023,7 +2023,7 @@ dfa_merge_nondistinguishable_states (struct REGEX_INTERNAL_Context *ctx, { for (s2 = a->states_head; NULL != s2 && s1 != s2; s2 = s2->next) { - idx = s1->marked * state_cnt + s2->marked; + idx = (unsigned long long) s1->marked * state_cnt + s2->marked; if (0 != (table[idx / 32] & (1 << (idx % 32)))) continue; num_equal_edges = 0; diff --git a/src/set/gnunet-service-set_union.c b/src/set/gnunet-service-set_union.c index aeb706ec3..c7f30a741 100644 --- a/src/set/gnunet-service-set_union.c +++ b/src/set/gnunet-service-set_union.c @@ -449,7 +449,7 @@ op_register_element (struct Operation *op, static void salt_key (const struct IBF_Key *k_in, - uint32_t salt, + uint32_t salt, struct IBF_Key *k_out) { int s = salt % 64; @@ -462,7 +462,7 @@ salt_key (const struct IBF_Key *k_in, static void unsalt_key (const struct IBF_Key *k_in, - uint32_t salt, + uint32_t salt, struct IBF_Key *k_out) { int s = salt % 64; @@ -752,6 +752,7 @@ handle_p2p_strata_estimator (void *cls, { /* decompression failed */ fail_union_operation (op); + strata_estimator_destroy (remote_se); return GNUNET_SYSERR; } GNUNET_assert (NULL != op->state->se); diff --git a/src/testbed-logger/testbed_logger_api.c b/src/testbed-logger/testbed_logger_api.c index de64048c5..9d8aa9ad3 100644 --- a/src/testbed-logger/testbed_logger_api.c +++ b/src/testbed-logger/testbed_logger_api.c @@ -312,7 +312,7 @@ GNUNET_TESTBED_LOGGER_flush (struct GNUNET_TESTBED_LOGGER_Handle *h, h->cb = cb; h->cb_cls = cb_cls; if ( (NULL == h->mq) || - (NULL == h->buf) ) + (0 == h->buse) ) { trigger_flush_notification (h); return; diff --git a/src/testbed/gnunet-daemon-testbed-blacklist.c b/src/testbed/gnunet-daemon-testbed-blacklist.c index 0cb83aacf..f2f96ee09 100644 --- a/src/testbed/gnunet-daemon-testbed-blacklist.c +++ b/src/testbed/gnunet-daemon-testbed-blacklist.c @@ -211,14 +211,13 @@ run (void *cls, GNUNET_asprintf (&fname, "%s/blacklist", shome); - GNUNET_free (fname); if (GNUNET_YES == GNUNET_DISK_file_test (fname)) { mode = ACCESS_DENY; setup_ac (shome, c); } GNUNET_free (shome); - return; + GNUNET_free (fname); } diff --git a/src/util/test_container_multihashmap.c b/src/util/test_container_multihashmap.c index bd193324c..a0ef8aa36 100644 --- a/src/util/test_container_multihashmap.c +++ b/src/util/test_container_multihashmap.c @@ -27,7 +27,7 @@ #include "platform.h" #include "gnunet_util_lib.h" -#define ABORT() { fprintf(stderr, "Error at %s:%d\n", __FILE__, __LINE__); if (m != NULL) GNUNET_CONTAINER_multihashmap_destroy(m); return 1; } +#define ABORT() { fprintf(stderr, "Error at %s:%d\n", __FILE__, __LINE__); if (m != NULL) GNUNET_CONTAINER_multihashmap_destroy(m); if (NULL != iter) GNUNET_CONTAINER_multihashmap_iterator_destroy (iter); return 1; } #define CHECK(c) { if (! (c)) ABORT(); } static int @@ -36,7 +36,7 @@ testMap (int i) struct GNUNET_CONTAINER_MultiHashMap *m; struct GNUNET_HashCode k1; struct GNUNET_HashCode k2; - struct GNUNET_CONTAINER_MultiHashMapIterator *iter; + struct GNUNET_CONTAINER_MultiHashMapIterator *iter = NULL; struct GNUNET_HashCode key_ret; const char *ret; int j; @@ -97,7 +97,7 @@ testMap (int i) for (j = 0; j < GNUNET_CONTAINER_multihashmap_size (m); j++) CHECK (GNUNET_YES == GNUNET_CONTAINER_multihashmap_iterator_next (iter, NULL, NULL)); CHECK (GNUNET_NO == GNUNET_CONTAINER_multihashmap_iterator_next (iter, NULL, NULL)); - GNUNET_free (iter); + GNUNET_CONTAINER_multihashmap_iterator_destroy (iter); GNUNET_CONTAINER_multihashmap_destroy (m); return 0; diff --git a/src/util/test_container_multipeermap.c b/src/util/test_container_multipeermap.c index f121281fa..65bed6606 100644 --- a/src/util/test_container_multipeermap.c +++ b/src/util/test_container_multipeermap.c @@ -27,7 +27,7 @@ #include "platform.h" #include "gnunet_util_lib.h" -#define ABORT() { fprintf(stderr, "Error at %s:%d\n", __FILE__, __LINE__); if (NULL != m) GNUNET_CONTAINER_multipeermap_destroy(m); return 1; } +#define ABORT() { fprintf(stderr, "Error at %s:%d\n", __FILE__, __LINE__); if (NULL != m) GNUNET_CONTAINER_multipeermap_destroy(m); if (NULL != iter) GNUNET_CONTAINER_multipeermap_iterator_destroy (iter); return 1; } #define CHECK(c) { if (! (c)) ABORT(); } static int @@ -36,7 +36,7 @@ testMap (int i) struct GNUNET_CONTAINER_MultiPeerMap *m; struct GNUNET_PeerIdentity k1; struct GNUNET_PeerIdentity k2; - struct GNUNET_CONTAINER_MultiPeerMapIterator *iter; + struct GNUNET_CONTAINER_MultiPeerMapIterator *iter = NULL; struct GNUNET_PeerIdentity key_ret; const char *ret; int j; @@ -97,7 +97,7 @@ testMap (int i) for (j = 0; j < GNUNET_CONTAINER_multipeermap_size (m); j++) CHECK (GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter, NULL, NULL)); CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_iterator_next (iter, NULL, NULL)); - GNUNET_free (iter); + GNUNET_CONTAINER_multipeermap_iterator_destroy (iter); GNUNET_CONTAINER_multipeermap_destroy (m); return 0; -- 2.25.1