X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=plugins%2Ftrimmer%2Ftrimmer.c;h=a68828931aa40988022e6aa7ecd3a9bbdf383387;hb=528debdf7f5593bfb1abddac48554fc635d26a6d;hp=7e6f024c94a0c368688fb55be6b096f38840dc81;hpb=cab3f160369bcc2536e536fa88ea76dd7bc586b4;p=babeltrace.git diff --git a/plugins/trimmer/trimmer.c b/plugins/trimmer/trimmer.c index 7e6f024c..a6882893 100644 --- a/plugins/trimmer/trimmer.c +++ b/plugins/trimmer/trimmer.c @@ -34,6 +34,7 @@ #include #include "trimmer.h" #include "iterator.h" +#include static void destroy_trimmer_data(struct trimmer *trimmer) @@ -62,6 +63,216 @@ void destroy_trimmer(struct bt_component *component) destroy_trimmer_data(data); } +/* + * Parses a timestamp, figuring out its format. + * + * Returns a negative value if anything goes wrong. + * + * Expected formats: + * + * YYYY-MM-DD hh:mm:ss.ns + * hh:mm:ss.ns + * -ss.ns + * ss.ns + * YYYY-MM-DD hh:mm:ss + * hh:mm:ss + * -ss + * ss + */ +static +int timestamp_from_arg(const char *arg, + struct trimmer_bound *result_bound, bool gmt) +{ + int ret; + int64_t value; + unsigned int year, month, day, hh, mm, ss, ns; + + /* YYYY-MM-DD hh:mm:ss.ns */ + ret = sscanf(arg, "%u-%u-%u %u:%u:%u.%u", + &year, &month, &day, &hh, &mm, &ss, &ns); + if (ret == 7) { + struct tm tm = { + .tm_sec = ss, + .tm_min = mm, + .tm_hour = hh, + .tm_mday = day, + .tm_mon = month - 1, + .tm_year = year - 1900, + .tm_isdst = -1, + }; + time_t result; + + if (gmt) { + result = timegm(&tm); + if (result < 0) { + return -1; + } + } else { + result = mktime(&tm); + if (result < 0) { + return -1; + } + } + value = (int64_t) result; + value *= NSEC_PER_SEC; + value += ns; + goto set; + } + /* hh:mm:ss.ns */ + ret = sscanf(arg, "%u:%u:%u.%u", + &hh, &mm, &ss, &ns); + if (ret == 4) { + /* We don't know which day until we get an event. */ + result_bound->lazy_values.hh = hh; + result_bound->lazy_values.mm = mm; + result_bound->lazy_values.ss = ss; + result_bound->lazy_values.ns = ns; + result_bound->lazy_values.gmt = gmt; + goto lazy; + } + /* -ss.ns */ + ret = sscanf(arg, "-%u.%u", + &ss, &ns); + if (ret == 2) { + value = -ss * NSEC_PER_SEC; + value -= ns; + goto set; + } + /* ss.ns */ + ret = sscanf(arg, "%u.%u", + &ss, &ns); + if (ret == 2) { + value = ss * NSEC_PER_SEC; + value += ns; + goto set; + } + + /* YYYY-MM-DD hh:mm:ss */ + ret = sscanf(arg, "%u-%u-%u %u:%u:%u", + &year, &month, &day, &hh, &mm, &ss); + if (ret == 6) { + struct tm tm = { + .tm_sec = ss, + .tm_min = mm, + .tm_hour = hh, + .tm_mday = day, + .tm_mon = month - 1, + .tm_year = year - 1900, + .tm_isdst = -1, + }; + + if (gmt) { + value = timegm(&tm); + if (value < 0) { + return -1; + } + } else { + value = mktime(&tm); + if (value < 0) { + return -1; + } + } + value *= NSEC_PER_SEC; + goto set; + } + /* hh:mm:ss */ + ret = sscanf(arg, "%u:%u:%u", + &hh, &mm, &ss); + if (ret == 3) { + /* We don't know which day until we get an event. */ + result_bound->lazy_values.hh = hh; + result_bound->lazy_values.mm = mm; + result_bound->lazy_values.ss = ss; + result_bound->lazy_values.ns = 0; + result_bound->lazy_values.gmt = gmt; + goto lazy; + } + /* -ss */ + ret = sscanf(arg, "-%u", + &ss); + if (ret == 1) { + value = -ss * NSEC_PER_SEC; + goto set; + } + /* ss */ + ret = sscanf(arg, "%u", + &ss); + if (ret == 1) { + value = ss * NSEC_PER_SEC; + goto set; + } + + /* Not found. */ + return -1; + +set: + result_bound->value = value; + result_bound->set = true; + return 0; + +lazy: + result_bound->lazy = true; + return 0; +} + +static +enum bt_component_status init_from_params(struct trimmer *trimmer, struct bt_value *params) +{ + struct bt_value *value = NULL; + bool gmt = false; + enum bt_component_status ret = BT_COMPONENT_STATUS_OK; + + assert(params); + + value = bt_value_map_get(params, "clock-gmt"); + if (value) { + enum bt_value_status value_ret; + + value_ret = bt_value_bool_get(value, &gmt); + if (value_ret) { + ret = BT_COMPONENT_STATUS_INVALID; + printf_error("Failed to retrieve clock-gmt value. Expecting a boolean.\n"); + } + } + bt_put(value); + if (ret != BT_COMPONENT_STATUS_OK) { + goto end; + } + + value = bt_value_map_get(params, "begin"); + if (value) { + enum bt_value_status value_ret; + const char *str; + + value_ret = bt_value_string_get(value, &str); + if (value_ret || timestamp_from_arg(str, + &trimmer->begin, gmt)) { + ret = BT_COMPONENT_STATUS_INVALID; + printf_error("Failed to retrieve begin value. Expecting a timestamp string.\n"); + } + } + bt_put(value); + if (ret != BT_COMPONENT_STATUS_OK) { + goto end; + } + + value = bt_value_map_get(params, "end"); + if (value) { + enum bt_value_status value_ret; + const char *str; + + value_ret = bt_value_string_get(value, &str); + if (value_ret || timestamp_from_arg(str, + &trimmer->end, gmt)) { + ret = BT_COMPONENT_STATUS_INVALID; + printf_error("Failed to retrieve end value. Expecting a timestamp string.\n"); + } + } + bt_put(value); +end: + return ret; +} + enum bt_component_status trimmer_component_init( struct bt_component *component, struct bt_value *params) { @@ -89,6 +300,8 @@ enum bt_component_status trimmer_component_init( if (ret != BT_COMPONENT_STATUS_OK) { goto error; } + + ret = init_from_params(trimmer, params); end: return ret; error: @@ -97,7 +310,7 @@ error: } /* Initialize plug-in entry points. */ -BT_PLUGIN_NAME("trimmer"); +BT_PLUGIN_NAME("utils"); BT_PLUGIN_DESCRIPTION("Babeltrace Trace Trimmer Plug-In."); BT_PLUGIN_AUTHOR("Jérémie Galarneau"); BT_PLUGIN_LICENSE("MIT");