Re: [PATCH 01/99] lib: Add option iterator

From: Thomas Zimmermann
Date: Tue Mar 07 2023 - 03:41:05 EST


Hi

Am 06.03.23 um 23:37 schrieb Randy Dunlap:
[...]
+ *
+ * The call to option_iter_init() initializes the iterator instance
+ * from the option string. The while loop walks over the individual
+ * options in the sting and returns each in the second argument. The
+ * returned memory is owned by the iterator instance and callers may
+ * not modify or free it. The call to option_iter_release() frees all
+ * resources of the iterator. This process does not modify the original
+ * option string. If the option string contains an empty option (i.e.,
+ * two commas next to each other), option_iter_next() skips the empty
+ * option automatically.

Is that latter skipping over a ",," automatically something that you have
observed as needed?

It's not strictly needed for correctness, but many of those fbdev drivers contain code to do that. Like this one:


https://elixir.bootlin.com/linux/v6.2/source/drivers/video/fbdev/vesafb.c#L217

So doing it in the _incr() helper seems useful

I can imagine a driver or module wanting to know that an empty string
was entered (i.e., ",,").

I only looked at fbdev drivers, but none of them cared about empty strings. They all have named options and/or key-value pairs.


+ */
+
+/**
+ * option_iter_init - Initializes an option iterator
+ * @iter: the iterator to initialize
+ * @options: the options string
+ */
+void option_iter_init(struct option_iter *iter, const char *options)
+{
+ if (options && *options)
+ iter->optbuf = kstrdup(options, GFP_KERNEL); // can be NULL
+ else
+ iter->optbuf = NULL;
+ iter->next_opt = iter->optbuf;
+}
+EXPORT_SYMBOL(option_iter_init);
+
+/**
+ * option_iter_release - Releases an option iterator's resources
+ * @iter: the iterator
+ */
+void option_iter_release(struct option_iter *iter)
+{
+ kfree(iter->optbuf);
+ iter->next_opt = NULL;
+}
+EXPORT_SYMBOL(option_iter_release);
+
+/**
+ * option_iter_incr - Return current option and advance to the next
+ * @iter: the iterator
+ *
+ * Returns:

* Return:
matches kernel-doc notation documentation.

+ * The current option string, or NULL if there are no more options.
+ */
+const char *option_iter_incr(struct option_iter *iter)
+{
+ char *opt;
+
+ if (!iter->next_opt) { // can be OK if kstrdup failed
+ if (iter->optbuf) // iter has already been released; logic error
+ pr_err("Incrementing option iterator without string\n");
+ return NULL;
+ }
+
+ do {
+ opt = strsep(&iter->next_opt, ",");
+ if (!opt)
+ return NULL;
+ } while (!*opt); // found empty option string, try next
+
+ return opt;
+}
+EXPORT_SYMBOL(option_iter_incr);

Looks useful. Thanks.

Thanks.

Best regards
Thomas



--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev

Attachment: OpenPGP_signature
Description: OpenPGP digital signature