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