18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef __PERF_STRLIST_H
38c2ecf20Sopenharmony_ci#define __PERF_STRLIST_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <linux/rbtree.h>
68c2ecf20Sopenharmony_ci#include <stdbool.h>
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include "rblist.h"
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_cistruct str_node {
118c2ecf20Sopenharmony_ci	struct rb_node rb_node;
128c2ecf20Sopenharmony_ci	const char     *s;
138c2ecf20Sopenharmony_ci};
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_cistruct strlist {
168c2ecf20Sopenharmony_ci	struct rblist rblist;
178c2ecf20Sopenharmony_ci	bool	      dupstr;
188c2ecf20Sopenharmony_ci	bool	      file_only;
198c2ecf20Sopenharmony_ci};
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci/*
228c2ecf20Sopenharmony_ci * @file_only: When dirname is present, only consider entries as filenames,
238c2ecf20Sopenharmony_ci *             that should not be added to the list if dirname/entry is not
248c2ecf20Sopenharmony_ci *             found
258c2ecf20Sopenharmony_ci */
268c2ecf20Sopenharmony_cistruct strlist_config {
278c2ecf20Sopenharmony_ci	bool dont_dupstr;
288c2ecf20Sopenharmony_ci	bool file_only;
298c2ecf20Sopenharmony_ci	const char *dirname;
308c2ecf20Sopenharmony_ci};
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_cistruct strlist *strlist__new(const char *slist, const struct strlist_config *config);
338c2ecf20Sopenharmony_civoid strlist__delete(struct strlist *slist);
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_civoid strlist__remove(struct strlist *slist, struct str_node *sn);
368c2ecf20Sopenharmony_ciint strlist__load(struct strlist *slist, const char *filename);
378c2ecf20Sopenharmony_ciint strlist__add(struct strlist *slist, const char *str);
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_cistruct str_node *strlist__entry(const struct strlist *slist, unsigned int idx);
408c2ecf20Sopenharmony_cistruct str_node *strlist__find(struct strlist *slist, const char *entry);
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_cistatic inline bool strlist__has_entry(struct strlist *slist, const char *entry)
438c2ecf20Sopenharmony_ci{
448c2ecf20Sopenharmony_ci	return strlist__find(slist, entry) != NULL;
458c2ecf20Sopenharmony_ci}
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_cistatic inline bool strlist__empty(const struct strlist *slist)
488c2ecf20Sopenharmony_ci{
498c2ecf20Sopenharmony_ci	return rblist__empty(&slist->rblist);
508c2ecf20Sopenharmony_ci}
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_cistatic inline unsigned int strlist__nr_entries(const struct strlist *slist)
538c2ecf20Sopenharmony_ci{
548c2ecf20Sopenharmony_ci	return rblist__nr_entries(&slist->rblist);
558c2ecf20Sopenharmony_ci}
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci/* For strlist iteration */
588c2ecf20Sopenharmony_cistatic inline struct str_node *strlist__first(struct strlist *slist)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	struct rb_node *rn = rb_first_cached(&slist->rblist.entries);
618c2ecf20Sopenharmony_ci	return rn ? rb_entry(rn, struct str_node, rb_node) : NULL;
628c2ecf20Sopenharmony_ci}
638c2ecf20Sopenharmony_cistatic inline struct str_node *strlist__next(struct str_node *sn)
648c2ecf20Sopenharmony_ci{
658c2ecf20Sopenharmony_ci	struct rb_node *rn;
668c2ecf20Sopenharmony_ci	if (!sn)
678c2ecf20Sopenharmony_ci		return NULL;
688c2ecf20Sopenharmony_ci	rn = rb_next(&sn->rb_node);
698c2ecf20Sopenharmony_ci	return rn ? rb_entry(rn, struct str_node, rb_node) : NULL;
708c2ecf20Sopenharmony_ci}
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci/**
738c2ecf20Sopenharmony_ci * strlist_for_each      - iterate over a strlist
748c2ecf20Sopenharmony_ci * @pos:	the &struct str_node to use as a loop cursor.
758c2ecf20Sopenharmony_ci * @slist:	the &struct strlist for loop.
768c2ecf20Sopenharmony_ci */
778c2ecf20Sopenharmony_ci#define strlist__for_each_entry(pos, slist)	\
788c2ecf20Sopenharmony_ci	for (pos = strlist__first(slist); pos; pos = strlist__next(pos))
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci/**
818c2ecf20Sopenharmony_ci * strlist_for_each_safe - iterate over a strlist safe against removal of
828c2ecf20Sopenharmony_ci *                         str_node
838c2ecf20Sopenharmony_ci * @pos:	the &struct str_node to use as a loop cursor.
848c2ecf20Sopenharmony_ci * @n:		another &struct str_node to use as temporary storage.
858c2ecf20Sopenharmony_ci * @slist:	the &struct strlist for loop.
868c2ecf20Sopenharmony_ci */
878c2ecf20Sopenharmony_ci#define strlist__for_each_entry_safe(pos, n, slist)	\
888c2ecf20Sopenharmony_ci	for (pos = strlist__first(slist), n = strlist__next(pos); pos;\
898c2ecf20Sopenharmony_ci	     pos = n, n = strlist__next(n))
908c2ecf20Sopenharmony_ci#endif /* __PERF_STRLIST_H */
91