162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __PERF_STRLIST_H
362306a36Sopenharmony_ci#define __PERF_STRLIST_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/rbtree.h>
662306a36Sopenharmony_ci#include <stdbool.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "rblist.h"
962306a36Sopenharmony_ci
1062306a36Sopenharmony_cistruct str_node {
1162306a36Sopenharmony_ci	struct rb_node rb_node;
1262306a36Sopenharmony_ci	const char     *s;
1362306a36Sopenharmony_ci};
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_cistruct strlist {
1662306a36Sopenharmony_ci	struct rblist rblist;
1762306a36Sopenharmony_ci	bool	      dupstr;
1862306a36Sopenharmony_ci	bool	      file_only;
1962306a36Sopenharmony_ci};
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/*
2262306a36Sopenharmony_ci * @file_only: When dirname is present, only consider entries as filenames,
2362306a36Sopenharmony_ci *             that should not be added to the list if dirname/entry is not
2462306a36Sopenharmony_ci *             found
2562306a36Sopenharmony_ci */
2662306a36Sopenharmony_cistruct strlist_config {
2762306a36Sopenharmony_ci	bool dont_dupstr;
2862306a36Sopenharmony_ci	bool file_only;
2962306a36Sopenharmony_ci	const char *dirname;
3062306a36Sopenharmony_ci};
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_cistruct strlist *strlist__new(const char *slist, const struct strlist_config *config);
3362306a36Sopenharmony_civoid strlist__delete(struct strlist *slist);
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_civoid strlist__remove(struct strlist *slist, struct str_node *sn);
3662306a36Sopenharmony_ciint strlist__load(struct strlist *slist, const char *filename);
3762306a36Sopenharmony_ciint strlist__add(struct strlist *slist, const char *str);
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_cistruct str_node *strlist__entry(const struct strlist *slist, unsigned int idx);
4062306a36Sopenharmony_cistruct str_node *strlist__find(struct strlist *slist, const char *entry);
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_cistatic inline bool strlist__has_entry(struct strlist *slist, const char *entry)
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci	return strlist__find(slist, entry) != NULL;
4562306a36Sopenharmony_ci}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistatic inline bool strlist__empty(const struct strlist *slist)
4862306a36Sopenharmony_ci{
4962306a36Sopenharmony_ci	return rblist__empty(&slist->rblist);
5062306a36Sopenharmony_ci}
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_cistatic inline unsigned int strlist__nr_entries(const struct strlist *slist)
5362306a36Sopenharmony_ci{
5462306a36Sopenharmony_ci	return rblist__nr_entries(&slist->rblist);
5562306a36Sopenharmony_ci}
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci/* For strlist iteration */
5862306a36Sopenharmony_cistatic inline struct str_node *strlist__first(struct strlist *slist)
5962306a36Sopenharmony_ci{
6062306a36Sopenharmony_ci	struct rb_node *rn = rb_first_cached(&slist->rblist.entries);
6162306a36Sopenharmony_ci	return rn ? rb_entry(rn, struct str_node, rb_node) : NULL;
6262306a36Sopenharmony_ci}
6362306a36Sopenharmony_cistatic inline struct str_node *strlist__next(struct str_node *sn)
6462306a36Sopenharmony_ci{
6562306a36Sopenharmony_ci	struct rb_node *rn;
6662306a36Sopenharmony_ci	if (!sn)
6762306a36Sopenharmony_ci		return NULL;
6862306a36Sopenharmony_ci	rn = rb_next(&sn->rb_node);
6962306a36Sopenharmony_ci	return rn ? rb_entry(rn, struct str_node, rb_node) : NULL;
7062306a36Sopenharmony_ci}
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/**
7362306a36Sopenharmony_ci * strlist_for_each      - iterate over a strlist
7462306a36Sopenharmony_ci * @pos:	the &struct str_node to use as a loop cursor.
7562306a36Sopenharmony_ci * @slist:	the &struct strlist for loop.
7662306a36Sopenharmony_ci */
7762306a36Sopenharmony_ci#define strlist__for_each_entry(pos, slist)	\
7862306a36Sopenharmony_ci	for (pos = strlist__first(slist); pos; pos = strlist__next(pos))
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci/**
8162306a36Sopenharmony_ci * strlist_for_each_safe - iterate over a strlist safe against removal of
8262306a36Sopenharmony_ci *                         str_node
8362306a36Sopenharmony_ci * @pos:	the &struct str_node to use as a loop cursor.
8462306a36Sopenharmony_ci * @n:		another &struct str_node to use as temporary storage.
8562306a36Sopenharmony_ci * @slist:	the &struct strlist for loop.
8662306a36Sopenharmony_ci */
8762306a36Sopenharmony_ci#define strlist__for_each_entry_safe(pos, n, slist)	\
8862306a36Sopenharmony_ci	for (pos = strlist__first(slist), n = strlist__next(pos); pos;\
8962306a36Sopenharmony_ci	     pos = n, n = strlist__next(n))
9062306a36Sopenharmony_ci#endif /* __PERF_STRLIST_H */
91