_public_ int sd_bus_path_encode_many(char **out, const char *path_template, ...) {
        _cleanup_strv_free_ char **labels = NULL;
        char *path, *path_pos, **label_pos;
        const char *sep, *template_pos;
        size_t path_length;
        va_list list;
        int r;

        assert_return(out, -EINVAL);
        assert_return(path_template, -EINVAL);

        path_length = strlen(path_template);

        va_start(list, path_template);
        for (sep = strchr(path_template, '%'); sep; sep = strchr(sep + 1, '%')) {
                const char *arg;
                char *label;

                arg = va_arg(list, const char *);
                if (!arg) {
                        va_end(list);
                        return -EINVAL;
                }

                label = bus_label_escape(arg);
                if (!label) {
                        va_end(list);
                        return -ENOMEM;
                }

                r = strv_consume(&labels, label);
                if (r < 0) {
                        va_end(list);
                        return r;
                }

                /* add label length, but account for the format character */
                path_length += strlen(label) - 1;
        }
        va_end(list);

        path = malloc(path_length + 1);
        if (!path)
                return -ENOMEM;

        path_pos = path;
        label_pos = labels;

        for (template_pos = path_template; *template_pos; ) {
                sep = strchrnul(template_pos, '%');
                path_pos = mempcpy(path_pos, template_pos, sep - template_pos);
                if (!*sep)
                        break;

                path_pos = stpcpy(path_pos, *label_pos++);
                template_pos = sep + 1;
        }

        *path_pos = 0;
        *out = path;
        return 0;
}
_public_ int sd_bus_path_encode_many(char **out, const char *path_template, ...) {
        _cleanup_strv_free_ char **labels = NULL;
        char *path, *path_pos, **label_pos;
        const char *sep, *template_pos;
        size_t path_length;
        va_list list;
        int r;

        assert_return(out, -EINVAL);
        assert_return(path_template, -EINVAL);

        path_length = strlen(path_template);

        va_start(list, path_template);
        for (sep = strchr(path_template, '%'); sep; sep = strchr(sep + 1, '%')) {
                const char *arg;
                char *label;

                arg = va_arg(list, const char *);
                if (!arg) {
                        va_end(list);
                        return -EINVAL;
                }

                label = bus_label_escape(arg);
                if (!label) {
                        va_end(list);
                        return -ENOMEM;
                }

                r = strv_consume(&labels, label);
                if (r < 0) {
                        va_end(list);
                        return r;
                }

                 
                path_length += strlen(label) - 1;
        }
        va_end(list);

        path = malloc(path_length + 1);
        if (!path)
                return -ENOMEM;

        path_pos = path;
        label_pos = labels;

        for (template_pos = path_template; *template_pos; ) {
                sep = strchrnul(template_pos, '%');
                path_pos = mempcpy(path_pos, template_pos, sep - template_pos);
                if (!*sep)
                        break;

                path_pos = stpcpy(path_pos, *label_pos++);
                template_pos = sep + 1;
        }

        *path_pos = 0;
        *out = path;
        return 0;
}