diff --git a/src/core/core-command.c b/src/core/core-command.c index 61e9a0605..1cf4f6bd7 100644 --- a/src/core/core-command.c +++ b/src/core/core-command.c @@ -2035,7 +2035,7 @@ COMMAND_CALLBACK(debug) struct t_weechat_plugin *ptr_plugin; struct timeval time_start, time_end; char *result, *str_threshold; - long long threshold; + unsigned long long threshold; int debug; /* make C compiler happy */ @@ -2073,7 +2073,8 @@ COMMAND_CALLBACK(debug) if (string_strcmp (argv[1], "callbacks") == 0) { COMMAND_MIN_ARGS(3, argv[1]); - threshold = util_parse_delay (argv[2], 1); + if (!util_parse_delay (argv[2], 1, &threshold)) + COMMAND_ERROR; if (threshold > 0) { str_threshold = util_get_microseconds_string (threshold); @@ -6174,7 +6175,7 @@ command_repeat_timer_cb (const void *pointer, void *data, int remaining_calls) COMMAND_CALLBACK(repeat) { int arg_count, count, i; - long long interval; + unsigned long long interval; char *error; struct t_command_repeat *cmd_repeat; @@ -6189,9 +6190,8 @@ COMMAND_CALLBACK(repeat) if ((argc >= 5) && (string_strcmp (argv[1], "-interval") == 0)) { - interval = util_parse_delay (argv[2], 1000000); - if (interval < 0) - interval = 0; + if (!util_parse_delay (argv[2], 1000000, &interval)) + COMMAND_ERROR; interval /= 1000; arg_count = 3; } @@ -7871,7 +7871,7 @@ COMMAND_CALLBACK(version) COMMAND_CALLBACK(wait) { - long long delay; + unsigned long long delay; /* make C compiler happy */ (void) pointer; @@ -7879,7 +7879,8 @@ COMMAND_CALLBACK(wait) COMMAND_MIN_ARGS(3, ""); - delay = util_parse_delay (argv[1], 1000000); + if (!util_parse_delay (argv[1], 1000000, &delay)) + COMMAND_ERROR; if (delay < 1) COMMAND_ERROR; diff --git a/src/core/core-debug.c b/src/core/core-debug.c index 3f8326c5a..8afeaf255 100644 --- a/src/core/core-debug.c +++ b/src/core/core-debug.c @@ -865,7 +865,9 @@ debug_display_time_elapsed (struct timeval *time1, struct timeval *time2, gettimeofday (&debug_timeval_end, NULL); diff = util_timeval_diff (time1, time2); - str_diff = util_get_microseconds_string (diff); + if (diff < 0) + diff *= -1; + str_diff = util_get_microseconds_string ((unsigned long long)diff); if (display) { diff --git a/src/core/core-hook.c b/src/core/core-hook.c index 96388fa9d..73b9fce2d 100644 --- a/src/core/core-hook.c +++ b/src/core/core-hook.c @@ -523,7 +523,7 @@ hook_callback_end (struct t_hook *hook, struct t_hook_exec_cb *hook_exec_cb) time_diff = util_timeval_diff (&hook_exec_cb->start_time, &end_time); if (time_diff >= debug_long_callbacks) { - str_diff = util_get_microseconds_string (time_diff); + str_diff = util_get_microseconds_string ((unsigned long long)time_diff); log_printf ( _("debug: long callback: hook %s (%s), plugin: %s, " "subplugin: %s, time elapsed: %s"), diff --git a/src/core/core-sys.c b/src/core/core-sys.c index 68eff601f..b81b9ffb9 100644 --- a/src/core/core-sys.c +++ b/src/core/core-sys.c @@ -285,14 +285,14 @@ sys_display_rusage (void) #ifdef HAVE_SYS_RESOURCE_H struct rusage usage; char *str_time; - long long microseconds; + unsigned long long microseconds; gui_chat_printf (NULL, ""); gui_chat_printf (NULL, _("Resource usage (see \"man getrusage\" for help):")); getrusage (RUSAGE_SELF, &usage); /* ru_utime: user CPU time used */ - microseconds = ((long long)usage.ru_utime.tv_sec * 1000000) - + (long long)usage.ru_utime.tv_usec; + microseconds = ((unsigned long long)usage.ru_utime.tv_sec * 1000000) + + (unsigned long long)usage.ru_utime.tv_usec; str_time = util_get_microseconds_string (microseconds); if (str_time) { @@ -300,8 +300,8 @@ sys_display_rusage (void) free (str_time); } /* ru_stime: system CPU time used */ - microseconds = ((long long)usage.ru_stime.tv_sec * 1000000) - + (long long)usage.ru_stime.tv_usec; + microseconds = ((unsigned long long)usage.ru_stime.tv_sec * 1000000) + + (unsigned long long)usage.ru_stime.tv_usec; str_time = util_get_microseconds_string (microseconds); if (str_time) { diff --git a/src/core/core-util.c b/src/core/core-util.c index 4589b2b1a..8cd1fd75e 100644 --- a/src/core/core-util.c +++ b/src/core/core-util.c @@ -123,9 +123,9 @@ util_timeval_add (struct timeval *tv, long long interval) */ char * -util_get_microseconds_string (long long microseconds) +util_get_microseconds_string (unsigned long long microseconds) { - long long hour, min, sec, usec; + unsigned long long hour, min, sec, usec; char result[128]; usec = microseconds % 1000000; @@ -134,7 +134,7 @@ util_get_microseconds_string (long long microseconds) hour = (microseconds / 1000000) / 3600; snprintf (result, sizeof (result), - "%lld:%02lld:%02lld.%06lld", + "%llu:%02llu:%02llu.%06llu", hour, min, sec, usec); return strdup (result); @@ -534,18 +534,26 @@ util_get_time_diff (time_t time1, time_t time2, * - 60000000: minutes * - 3600000000: hours * - * Returns the delay in microseconds, -1 if error. + * Returns: + * 1: OK + * 0: error */ -long long -util_parse_delay (const char *string_delay, long long default_factor) +int +util_parse_delay (const char *string_delay, unsigned long long default_factor, + unsigned long long *delay) { const char *pos; char *str_number, *error; - long long factor, delay; + unsigned long long factor; + + if (!delay) + return 0; + + *delay = 0; if (!string_delay || !string_delay[0] || (default_factor < 1)) - return -1LL; + return 0; factor = default_factor; @@ -559,37 +567,42 @@ util_parse_delay (const char *string_delay, long long default_factor) { str_number = string_strndup (string_delay, pos - string_delay); if (strcmp (pos, "us") == 0) - factor = 1LL; + factor = 1ULL; else if (strcmp (pos, "ms") == 0) - factor = 1000LL; + factor = 1000ULL; else if (strcmp (pos, "s") == 0) - factor = 1000LL * 1000LL; + factor = 1000ULL * 1000ULL; else if (strcmp (pos, "m") == 0) - factor = 1000LL * 1000LL * 60LL; + factor = 1000ULL * 1000ULL * 60ULL; else if (strcmp (pos, "h") == 0) - factor = 1000LL * 1000LL * 60LL * 60LL; + factor = 1000ULL * 1000ULL * 60ULL * 60ULL; else - return -1LL; + return 0; } else { + if (string_delay[0] == '-') + return 0; str_number = strdup (string_delay); } if (!str_number) - return -1LL; + return 0; error = NULL; - delay = strtoll (str_number, &error, 10); - if (!error || error[0] || (delay < 0)) + *delay = strtoull (str_number, &error, 10); + if (!error || error[0]) { free (str_number); - return -1LL; + *delay = 0; + return 0; } + *delay *= factor; + free (str_number); - return delay * factor; + return 1; } /* diff --git a/src/core/core-util.h b/src/core/core-util.h index 413f20b6f..6350d6d92 100644 --- a/src/core/core-util.h +++ b/src/core/core-util.h @@ -29,7 +29,7 @@ extern long long util_timeval_diff (struct timeval *tv1, struct timeval *tv2); extern void util_timeval_add (struct timeval *tv, long long interval); /* time */ -extern char *util_get_microseconds_string (long long diff); +extern char *util_get_microseconds_string (unsigned long long microseconds); extern const char *util_get_time_string (const time_t *date); extern int util_strftimeval (char *string, int max, const char *format, struct timeval *tv); @@ -41,8 +41,9 @@ extern void util_get_time_diff (time_t time1, time_t time2, /* delay */ -extern long long util_parse_delay (const char *string_delay, - long long default_factor); +extern int util_parse_delay (const char *string_delay, + unsigned long long default_factor, + unsigned long long *delay); /* version */ extern int util_version_number (const char *version); diff --git a/src/gui/gui-bar-item.c b/src/gui/gui-bar-item.c index fecbb3fda..77f49dc06 100644 --- a/src/gui/gui-bar-item.c +++ b/src/gui/gui-bar-item.c @@ -435,7 +435,7 @@ gui_bar_item_get_value (struct t_gui_bar *bar, struct t_gui_window *window, time_diff = util_timeval_diff (&start_time, &end_time); if (time_diff >= debug_long_callbacks) { - str_diff = util_get_microseconds_string (time_diff); + str_diff = util_get_microseconds_string ((unsigned long long)time_diff); log_printf ( _("debug: long callback: bar: %s, item: %s, plugin: %s, " "time elapsed: %s"), diff --git a/tests/unit/core/test-core-util.cpp b/tests/unit/core/test-core-util.cpp index 2d755149f..c77a9544b 100644 --- a/tests/unit/core/test-core-util.cpp +++ b/tests/unit/core/test-core-util.cpp @@ -25,6 +25,7 @@ extern "C" { +#include #include #include #include @@ -42,6 +43,13 @@ extern "C" LONGS_EQUAL(__sec, tv.tv_sec); \ LONGS_EQUAL(__usec, tv.tv_usec); +#define WEE_PARSE_DELAY(__result, __result_delay, \ + __delay, __factor) \ + delay = ULLONG_MAX; \ + LONGS_EQUAL(__result, \ + util_parse_delay (__delay, __factor, &delay)); \ + CHECK(delay == __result_delay); + TEST_GROUP(CoreUtil) { }; @@ -108,30 +116,30 @@ TEST(CoreUtil, GetMicrosecondsString) /* zero */ WEE_TEST_STR("0:00:00.000000", - util_get_microseconds_string (0LL)); + util_get_microseconds_string (0ULL)); /* microseconds */ - WEE_TEST_STR("0:00:00.000001", util_get_microseconds_string (1LL)); - WEE_TEST_STR("0:00:00.000123", util_get_microseconds_string (123LL)); + WEE_TEST_STR("0:00:00.000001", util_get_microseconds_string (1ULL)); + WEE_TEST_STR("0:00:00.000123", util_get_microseconds_string (123ULL)); /* microseconds */ - WEE_TEST_STR("0:00:00.001000", util_get_microseconds_string (1LL * 1000LL)); - WEE_TEST_STR("0:00:00.123000", util_get_microseconds_string (123LL * 1000LL)); + WEE_TEST_STR("0:00:00.001000", util_get_microseconds_string (1ULL * 1000ULL)); + WEE_TEST_STR("0:00:00.123000", util_get_microseconds_string (123ULL * 1000ULL)); /* seconds */ - WEE_TEST_STR("0:00:01.000000", util_get_microseconds_string (1LL * 1000LL * 1000LL)); - WEE_TEST_STR("0:00:12.000000", util_get_microseconds_string (12LL * 1000LL * 1000LL)); + WEE_TEST_STR("0:00:01.000000", util_get_microseconds_string (1ULL * 1000ULL * 1000ULL)); + WEE_TEST_STR("0:00:12.000000", util_get_microseconds_string (12ULL * 1000ULL * 1000ULL)); /* minutes */ - WEE_TEST_STR("0:01:00.000000", util_get_microseconds_string (1LL * 60LL * 1000LL * 1000LL)); - WEE_TEST_STR("0:34:00.000000", util_get_microseconds_string (34LL * 60LL * 1000LL * 1000LL)); + WEE_TEST_STR("0:01:00.000000", util_get_microseconds_string (1ULL * 60ULL * 1000ULL * 1000ULL)); + WEE_TEST_STR("0:34:00.000000", util_get_microseconds_string (34ULL * 60ULL * 1000ULL * 1000ULL)); /* hours */ - WEE_TEST_STR("1:00:00.000000", util_get_microseconds_string (1LL * 60LL * 60LL * 1000LL * 1000LL)); - WEE_TEST_STR("34:00:00.000000", util_get_microseconds_string (34LL * 60LL * 60LL * 1000LL * 1000LL)); + WEE_TEST_STR("1:00:00.000000", util_get_microseconds_string (1ULL * 60ULL * 60ULL * 1000ULL * 1000ULL)); + WEE_TEST_STR("34:00:00.000000", util_get_microseconds_string (34ULL * 60ULL * 60ULL * 1000ULL * 1000ULL)); /* hours + minutes + seconds + milliseconds + microseconds */ - WEE_TEST_STR("3:25:45.678901", util_get_microseconds_string (12345678901LL)); + WEE_TEST_STR("3:25:45.678901", util_get_microseconds_string (12345678901ULL)); } /* @@ -425,60 +433,64 @@ TEST(CoreUtil, GetTimeDiff) TEST(CoreUtil, ParseDelay) { + unsigned long long delay; + + /* error: no delay */ + LONGS_EQUAL(0, util_parse_delay ("123", 1ULL, NULL)); + /* error: no string */ - LONGS_EQUAL(-1LL, util_parse_delay (NULL, -1LL)); - LONGS_EQUAL(-1LL, util_parse_delay (NULL, 0LL)); - LONGS_EQUAL(-1LL, util_parse_delay (NULL, 1LL)); - LONGS_EQUAL(-1LL, util_parse_delay ("", -1LL)); - LONGS_EQUAL(-1LL, util_parse_delay ("", 0LL)); - LONGS_EQUAL(-1LL, util_parse_delay ("", 1LL)); + WEE_PARSE_DELAY(0, 0ULL, NULL, 0ULL); + WEE_PARSE_DELAY(0, 0ULL, NULL, 1ULL); + WEE_PARSE_DELAY(0, 0ULL, "", 0ULL); + WEE_PARSE_DELAY(0, 0ULL, "", 1ULL); /* error: bad default_factor */ - LONGS_EQUAL(-1LL, util_parse_delay ("abcd", -1LL)); - LONGS_EQUAL(-1LL, util_parse_delay ("abcd", 0LL)); - LONGS_EQUAL(-1LL, util_parse_delay ("123", -1LL)); - LONGS_EQUAL(-1LL, util_parse_delay ("123", 0LL)); + WEE_PARSE_DELAY(0, 0ULL, "abcd", 0ULL); + WEE_PARSE_DELAY(0, 0ULL, "123", 0ULL); /* error: bad unit */ - LONGS_EQUAL(-1LL, util_parse_delay ("123a", 1LL)); - LONGS_EQUAL(-1LL, util_parse_delay ("123ss", 1LL)); - LONGS_EQUAL(-1LL, util_parse_delay ("123mss", 1LL)); - LONGS_EQUAL(-1LL, util_parse_delay ("123uss", 1LL)); + WEE_PARSE_DELAY(0, 0ULL, "123a", 1ULL); + WEE_PARSE_DELAY(0, 0ULL, "123ss", 1ULL); + WEE_PARSE_DELAY(0, 0ULL, "123mss", 1ULL); + WEE_PARSE_DELAY(0, 0ULL, "123uss", 1ULL); /* error: bad number */ - LONGS_EQUAL(-1LL, util_parse_delay ("abcd", 1LL)); + WEE_PARSE_DELAY(0, 0ULL, "abcd", 1LL); + + /* error: bad delay */ + WEE_PARSE_DELAY(0, 0ULL, "-123", 1LL); /* tests with delay == 0 */ - LONGS_EQUAL(0LL, util_parse_delay ("0", 1LL)); - LONGS_EQUAL(0LL, util_parse_delay ("0us", 1LL)); - LONGS_EQUAL(0LL, util_parse_delay ("0ms", 1LL)); - LONGS_EQUAL(0LL, util_parse_delay ("0s", 1LL)); - LONGS_EQUAL(0LL, util_parse_delay ("0m", 1LL)); - LONGS_EQUAL(0LL, util_parse_delay ("0h", 1LL)); + WEE_PARSE_DELAY(1, 0ULL, "0", 1ULL); + WEE_PARSE_DELAY(1, 0ULL, "0us", 1ULL); + WEE_PARSE_DELAY(1, 0ULL, "0ms", 1ULL); + WEE_PARSE_DELAY(1, 0ULL, "0s", 1ULL); + WEE_PARSE_DELAY(1, 0ULL, "0m", 1ULL); + WEE_PARSE_DELAY(1, 0ULL, "0h", 1ULL); /* tests with delay == 123, default_factor = 1 (1 microsecond) */ - LONGS_EQUAL(123LL, util_parse_delay ("123", 1LL)); - LONGS_EQUAL(123LL, util_parse_delay ("123us", 1LL)); - LONGS_EQUAL(123LL * 1000LL, util_parse_delay ("123ms", 1LL)); - LONGS_EQUAL(123LL * 1000LL * 1000LL, util_parse_delay ("123s", 1LL)); - LONGS_EQUAL(123LL * 1000LL * 1000LL * 60LL, util_parse_delay ("123m", 1LL)); - LONGS_EQUAL(123LL * 1000LL * 1000LL * 60LL * 60LL, util_parse_delay ("123h", 1LL)); + WEE_PARSE_DELAY(1, 123ULL, "123", 1ULL); + WEE_PARSE_DELAY(1, 123ULL, "123us", 1ULL); + WEE_PARSE_DELAY(1, 123ULL * 1000ULL, "123ms", 1ULL); + WEE_PARSE_DELAY(1, 123ULL * 1000ULL * 1000ULL, "123s", 1ULL); + WEE_PARSE_DELAY(1, 123ULL * 1000ULL * 1000ULL * 60ULL, "123m", 1ULL); + WEE_PARSE_DELAY(1, 123ULL * 1000ULL * 1000ULL * 60ULL * 60ULL, "123h", 1ULL); /* tests with delay == 123, default_factor = 1000 (1 millisecond) */ - LONGS_EQUAL(123LL * 1000LL, util_parse_delay ("123", 1000LL)); - LONGS_EQUAL(123LL, util_parse_delay ("123us", 1000LL)); - LONGS_EQUAL(123LL * 1000LL, util_parse_delay ("123ms", 1000LL)); - LONGS_EQUAL(123LL * 1000LL * 1000LL, util_parse_delay ("123s", 1000LL)); - LONGS_EQUAL(123LL * 1000LL * 1000LL * 60LL, util_parse_delay ("123m", 1000LL)); - LONGS_EQUAL(123LL * 1000LL * 1000LL * 60LL * 60LL, util_parse_delay ("123h", 1000LL)); + WEE_PARSE_DELAY(1, 123ULL * 1000ULL, "123", 1000ULL); + WEE_PARSE_DELAY(1, 123ULL, "123us", 1000ULL); + WEE_PARSE_DELAY(1, 123ULL * 1000ULL, "123ms", 1000ULL); + WEE_PARSE_DELAY(1, 123ULL * 1000ULL * 1000ULL, "123s", 1000ULL); + WEE_PARSE_DELAY(1, 123ULL * 1000ULL * 1000ULL * 60ULL, "123m", 1000ULL); + WEE_PARSE_DELAY(1, 123ULL * 1000ULL * 1000ULL * 60ULL * 60ULL, "123h", 1000ULL); /* tests with delay == 123, default_factor = 1000000 (1 second) */ - LONGS_EQUAL(123LL * 1000LL * 1000LL, util_parse_delay ("123", 1000000LL)); - LONGS_EQUAL(123LL, util_parse_delay ("123us", 1000000LL)); - LONGS_EQUAL(123LL * 1000LL, util_parse_delay ("123ms", 1000000LL)); - LONGS_EQUAL(123LL * 1000LL * 1000LL, util_parse_delay ("123s", 1000000LL)); - LONGS_EQUAL(123LL * 1000LL * 1000LL * 60LL, util_parse_delay ("123m", 1000000LL)); - LONGS_EQUAL(123LL * 1000LL * 1000LL * 60LL * 60LL, util_parse_delay ("123h", 1000000LL)); + WEE_PARSE_DELAY(1, 123ULL * 1000ULL * 1000ULL, "123", 1000000ULL); + WEE_PARSE_DELAY(1, 123ULL, "123us", 1000000ULL); + WEE_PARSE_DELAY(1, 123ULL * 1000ULL, "123ms", 1000000ULL); + WEE_PARSE_DELAY(1, 123ULL * 1000ULL * 1000ULL, "123s", 1000000ULL); + WEE_PARSE_DELAY(1, 123ULL * 1000ULL * 1000ULL * 60ULL, "123m", 1000000ULL); + WEE_PARSE_DELAY(1, 123ULL * 1000ULL * 1000ULL * 60ULL * 60ULL, "123h", 1000000ULL); } /*