+
+static struct lttng_rate_policy *parse_rate_policy(const char *policy_str)
+{
+ int ret;
+ size_t num_token = 0;
+ struct lttng_dynamic_pointer_array tokens;
+ struct lttng_rate_policy *policy = NULL;
+ enum lttng_rate_policy_type policy_type;
+ unsigned long long value;
+ char *policy_type_str;
+ char *policy_value_str;
+
+ assert(policy_str);
+ lttng_dynamic_pointer_array_init(&tokens, NULL);
+
+ /* Rate policy fields are separated by ':'. */
+ ret = strutils_split(policy_str, ':', 1, &tokens);
+ if (ret == 0) {
+ num_token = lttng_dynamic_pointer_array_get_count(&tokens);
+ }
+
+ /*
+ * Early sanity check that the number of parameter is exactly 2.
+ * i.e : type:value
+ */
+ if (num_token != 2) {
+ ERR("Rate policy format is invalid.");
+ goto end;
+ }
+
+ policy_type_str = lttng_dynamic_pointer_array_get_pointer(&tokens, 0);
+ policy_value_str = lttng_dynamic_pointer_array_get_pointer(&tokens, 1);
+
+ /* Parse the type. */
+ if (strcmp(policy_type_str, "once-after") == 0) {
+ policy_type = LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N;
+ } else if (strcmp(policy_type_str, "every") == 0) {
+ policy_type = LTTNG_RATE_POLICY_TYPE_EVERY_N;
+ } else {
+ ERR("Rate policy type `%s` unknown.", policy_type_str);
+ goto end;
+ }
+
+ /* Parse the value. */
+ if (utils_parse_unsigned_long_long(policy_value_str, &value) != 0) {
+ ERR("Failed to parse rate policy value `%s` as an integer.",
+ policy_value_str);
+ goto end;
+ }
+
+ if (value == 0) {
+ ERR("Rate policy value `%s` must be > 0.", policy_value_str);
+ goto end;
+ }
+
+ switch (policy_type) {
+ case LTTNG_RATE_POLICY_TYPE_EVERY_N:
+ policy = lttng_rate_policy_every_n_create(value);
+ break;
+ case LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N:
+ policy = lttng_rate_policy_once_after_n_create(value);
+ break;
+ default:
+ abort();
+ }
+
+ if (policy == NULL) {
+ ERR("Failed to create rate policy `%s`.", policy_str);
+ }
+
+end:
+ lttng_dynamic_pointer_array_reset(&tokens);
+ return policy;
+}
+