XenevaOS
Loading...
Searching...
No Matches
seq_buf.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _LINUX_SEQ_BUF_H
3#define _LINUX_SEQ_BUF_H
4
5#include <linux/bug.h>
6#include <linux/minmax.h>
7#include <linux/path.h>
8#include <linux/seq_file.h>
9#include <linux/types.h>
10
11/*
12 * <linux/path.h> is the one include mainline does not spell here: it arrives
13 * through <linux/seq_file.h> -> <linux/fs.h> there, while DCL's seq_file.h
14 * stops at <linux/kernel.h> and its fs.h carries no struct path either --
15 * so the `const struct path *` below had no file-scope tag to point at. A
16 * struct named only inside a prototype lives in that prototype's scope,
17 * which is why lib/seq_buf.c:313 then failed with "conflicting types" *and*
18 * "declaration of 'struct path' will not be visible outside of this
19 * function": two different `struct path`s.
20 *
21 * Trace sequences are used to allow a function to call several other
22 * functions to create a string of data to use.
23 */
24
31struct seq_buf {
32 char *buffer;
33 size_t size;
34 size_t len;
35};
36
37#define DECLARE_SEQ_BUF(NAME, SIZE) \
38 struct seq_buf NAME = { \
39 .buffer = (char[SIZE]) { 0 }, \
40 .size = SIZE, \
41 }
42
43static inline void seq_buf_clear(struct seq_buf *s)
44{
45 s->len = 0;
46 if (s->size)
47 s->buffer[0] = '\0';
48}
49
50static inline void
51seq_buf_init(struct seq_buf *s, char *buf, unsigned int size)
52{
53 s->buffer = buf;
54 s->size = size;
55 seq_buf_clear(s);
56}
57
58/*
59 * seq_buf have a buffer that might overflow. When this happens
60 * len is set to be greater than size.
61 */
62static inline bool
63seq_buf_has_overflowed(struct seq_buf *s)
64{
65 return s->len > s->size;
66}
67
68static inline void
69seq_buf_set_overflow(struct seq_buf *s)
70{
71 s->len = s->size + 1;
72}
73
74/*
75 * How much buffer is left on the seq_buf?
76 */
77static inline unsigned int
78seq_buf_buffer_left(struct seq_buf *s)
79{
80 if (seq_buf_has_overflowed(s))
81 return 0;
82
83 return s->size - s->len;
84}
85
86/* How much buffer was written? */
87static inline unsigned int seq_buf_used(struct seq_buf *s)
88{
89 return min(s->len, s->size);
90}
91
108static inline const char *seq_buf_str(struct seq_buf *s)
109{
110 if (WARN_ON(s->size == 0))
111 return "";
112
113 if (seq_buf_buffer_left(s))
114 s->buffer[s->len] = 0;
115 else
116 s->buffer[s->size - 1] = 0;
117
118 return s->buffer;
119}
120
129static inline size_t seq_buf_get_buf(struct seq_buf *s, char **bufp)
130{
131 WARN_ON(s->len > s->size + 1);
132
133 if (s->len < s->size) {
134 *bufp = s->buffer + s->len;
135 return s->size - s->len;
136 }
137
138 *bufp = NULL;
139 return 0;
140}
141
151static inline void seq_buf_commit(struct seq_buf *s, int num)
152{
153 if (num < 0) {
154 seq_buf_set_overflow(s);
155 } else {
156 /* num must be negative on overflow */
157 BUG_ON(s->len + num > s->size);
158 s->len += num;
159 }
160}
161
170static inline int seq_buf_pop(struct seq_buf *s)
171{
172 if (!s->len)
173 return -1;
174
175 s->len--;
176 return (unsigned int)s->buffer[s->len];
177}
178
179extern __printf(2, 3)
180int seq_buf_printf(struct seq_buf *s, const char *fmt, ...);
181extern __printf(2, 0)
182int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args);
183extern int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s);
184extern int seq_buf_to_user(struct seq_buf *s, char __user *ubuf,
185 size_t start, int cnt);
186extern int seq_buf_puts(struct seq_buf *s, const char *str);
187extern int seq_buf_putc(struct seq_buf *s, unsigned char c);
188extern int seq_buf_putmem(struct seq_buf *s, const void *mem, unsigned int len);
189extern int seq_buf_putmem_hex(struct seq_buf *s, const void *mem,
190 unsigned int len);
191extern int seq_buf_path(struct seq_buf *s, const struct path *path, const char *esc);
192extern int seq_buf_hex_dump(struct seq_buf *s, const char *prefix_str,
193 int prefix_type, int rowsize, int groupsize,
194 const void *buf, size_t len, bool ascii);
195
196#ifdef CONFIG_BINARY_PRINTF
197__printf(2, 0)
198int seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary);
199#endif
200
201void seq_buf_do_printk(struct seq_buf *s, const char *lvl);
202
203#endif /* _LINUX_SEQ_BUF_H */
char * va_list
Definition acmsvcex.h:186
#define NULL
Definition actypes.h:561
#define __printf(fmt_idx, arg_idx)
Definition compiler.h:144
#define __user
Definition compiler.h:63
size_t size
Definition drm_bridge.h:1299
size_t len
Definition initial.c:23
#define BUG_ON(condition)
Definition kernel.h:730
uint32_t u32
Definition kernel.h:16
#define min(a, b)
Definition minmax.h:24
int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, size_t start, int cnt)
int seq_buf_puts(struct seq_buf *s, const char *str)
void seq_buf_do_printk(struct seq_buf *s, const char *lvl)
int seq_buf_hex_dump(struct seq_buf *s, const char *prefix_str, int prefix_type, int rowsize, int groupsize, const void *buf, size_t len, bool ascii)
const char const char va_list args
Definition seq_buf.h:182
int seq_buf_putmem_hex(struct seq_buf *s, const void *mem, unsigned int len)
int seq_buf_putc(struct seq_buf *s, unsigned char c)
int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s)
const char * fmt
Definition seq_buf.h:180
int seq_buf_path(struct seq_buf *s, const struct path *path, const char *esc)
int seq_buf_putmem(struct seq_buf *s, const void *mem, unsigned int len)
Definition path.h:8
Definition seq_buf.h:31
char * buffer
Definition seq_buf.h:32
size_t size
Definition seq_buf.h:33
size_t len
Definition seq_buf.h:34
Definition seq_file.h:47