rdline: support pager during completion
[libcmdline.git] / src / lib / cmdline_rdline.h
1 /*-
2  * Copyright (c) <2010>, Intel Corporation
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * - Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
12  * - Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in
14  *   the documentation and/or other materials provided with the
15  *   distribution.
16  *
17  * - Neither the name of Intel Corporation nor the names of its
18  *   contributors may be used to endorse or promote products derived
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
30  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
32  * OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 /*
36  * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
37  * All rights reserved.
38  * Redistribution and use in source and binary forms, with or without
39  * modification, are permitted provided that the following conditions are met:
40  *
41  *     * Redistributions of source code must retain the above copyright
42  *       notice, this list of conditions and the following disclaimer.
43  *     * Redistributions in binary form must reproduce the above copyright
44  *       notice, this list of conditions and the following disclaimer in the
45  *       documentation and/or other materials provided with the distribution.
46  *     * Neither the name of the University of California, Berkeley nor the
47  *       names of its contributors may be used to endorse or promote products
48  *       derived from this software without specific prior written permission.
49  *
50  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
51  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
54  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
55  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
56  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
57  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60  */
61
62 #ifndef _RDLINE_H_
63 #define _RDLINE_H_
64
65 /**
66  * This file is a small equivalent to the GNU readline library, it was
67  * originally designed for very small systems (an 8-bits Atmel AVR
68  * microcontroller), but the library can now run on many emmbedded
69  * systems with or without OS.
70  *
71  * Obviously, it does not support as many things as the GNU readline,
72  * but at least it supports some interresting features like a kill
73  * buffer and a command history.
74  *
75  * It also have a feature that does not have the GNU readline (as far
76  * as I know): it is possible to have several instances of readline
77  * running at the same time, even on a monothread program, since it
78  * works with callbacks.
79  */
80
81 #include <cmdline_cirbuf.h>
82 #include <cmdline_vt100.h>
83
84 /* configuration */
85 #define RDLINE_BUF_SIZE 256
86 #define RDLINE_PROMPT_SIZE  32
87 #define RDLINE_VT100_BUF_SIZE  8
88 #define RDLINE_HISTORY_BUF_SIZE BUFSIZ
89 #define RDLINE_HISTORY_MAX_LINE 64
90 #define RDLINE_MAX_LINES 23
91
92 enum rdline_status {
93         RDLINE_INIT,
94         RDLINE_RUNNING,
95         RDLINE_EXITED
96 };
97
98 struct rdline;
99
100 /**
101  * callback given to rdline_help() to display the content of the
102  * help. The first argument is an opaque pointer. The other args
103  * are buffer and size.
104  */
105 typedef ssize_t (rdline_write_t)(struct rdline *, void *, size_t);
106
107
108 typedef void (rdline_validate_t)(struct rdline *rdl,
109                                  const char *buf, unsigned int size);
110 typedef int (rdline_complete_t)(struct rdline *rdl, const char *buf,
111                                 char *dstbuf, unsigned int dstsize);
112 typedef int (rdline_help_t)(struct rdline *rdl, const char *buf,
113                             rdline_write_t *write, void *opaque);
114
115 typedef void (rdline_asyncpager_cb_t)(struct rdline *, void *);
116
117 struct rdline {
118         enum rdline_status status;
119         int fd_in;
120         int fd_out;
121
122         /* rdline bufs */
123         struct cirbuf left;
124         struct cirbuf right;
125         char left_buf[RDLINE_BUF_SIZE+2]; /* reserve 2 chars for the \n\0 */
126         char right_buf[RDLINE_BUF_SIZE];
127
128         char prompt[RDLINE_PROMPT_SIZE];
129
130 #ifndef NO_RDLINE_KILL_BUF
131         char kill_buf[RDLINE_BUF_SIZE];
132         unsigned int kill_size;
133 #endif
134
135 #ifndef NO_RDLINE_HISTORY
136         /* history */
137         struct cirbuf history;
138         char history_buf[RDLINE_HISTORY_BUF_SIZE];
139         int history_cur_line;
140 #endif
141
142         /* callbacks and func pointers */
143         rdline_validate_t *validate;
144         rdline_complete_t *complete;
145         rdline_help_t *help;
146
147         /* vt100 parser */
148         struct cmdline_vt100 vt100;
149
150         /* opaque pointer */
151         void *opaque;
152
153 #ifndef NO_PAGER
154         char *pager_buf; /* buffer used to store paged data */
155         int pager_len; /* total len of buffer */
156         int pager_off; /* offset of next data */
157         int pager_lines; /* number of lines displayed */
158         rdline_asyncpager_cb_t *pager_cb;
159         void *pager_arg;
160 #endif
161 };
162
163 /**
164  * Init fields for a struct rdline.
165  *
166  * @param rdl A pointer to an uninitialized struct rdline
167  * @param fd_in
168  *   Input file descriptor
169  * @param fd_out
170  *   Output file descriptor
171  * @param validate
172  *   A pointer to the function to execute when the user validates the
173  *   buffer.
174  * @param complete
175  *   A pointer to the function to execute when the user completes the
176  *   buffer.
177  * @param help
178  *   A pointer to the function to execute when the user ask for
179  *   contextual help.
180  */
181 void rdline_init(struct rdline *rdl,
182                  int fd_in, int fd_out,
183                  rdline_validate_t *validate,
184                  rdline_complete_t *complete,
185                  rdline_help_t *help);
186
187
188 /**
189  * Init the current buffer, and display a prompt.
190  *
191  * Also set the rdline status to "running", overriding previous
192  * rdline_stop() or rdline_quit().
193  *
194  * @param rdl
195  *   A pointer to an initialized struct rdline
196  * @param prompt
197  *   A string containing the prompt
198  */
199 void rdline_newline(struct rdline *rdl, const char *prompt);
200
201 /**
202  * Ignore all subsequent received chars.
203  *
204  * @param rdl
205  *   A pointer to a struct rdline
206  */
207 void rdline_stop(struct rdline *rdl);
208
209 /**
210  * Exit from running rdline loop
211  *
212  * Same than rdline_stop() except that next calls to rdline_char_in()
213  * will return RDLINE_RES_EXITED. Hence, any running rdline() function is
214  * interrupted.
215  *
216  * @param rdl
217  *   A pointer to a struct rdline
218  */
219 void rdline_quit(struct rdline *rdl);
220
221 /**
222  * Restart after a call to rdline_stop() or rdline_quit()
223  *
224  * @param rdl
225  *   A pointer to a struct rdline
226  */
227 void rdline_restart(struct rdline *rdl);
228
229 /**
230  * Redisplay the current buffer
231  *
232  * @param rdl
233  *   A pointer to a struct rdline
234  */
235 void rdline_redisplay(struct rdline *rdl);
236
237
238 /* return status for rdline_char_in() */
239 #define RDLINE_RES_SUCCESS       0
240 #define RDLINE_RES_VALIDATED     1
241 #define RDLINE_RES_NOT_RUNNING  -1
242 #define RDLINE_RES_EOF          -2
243 #define RDLINE_RES_EXITED       -3
244
245 /**
246  * Append a char to the readline buffer.
247  *
248  * @param rdl
249  *   A pointer to a struct rdline
250  * @param c
251  *   The character to append
252  * @return
253  *   - RDLINE_RES_VALIDATED when the line has been validated.
254  *   - RDLINE_RES_NOT_RUNNING if it is not running.
255  *   - RDLINE_RES_EOF if EOF (ctrl-d on an empty line).
256  *   - RDLINE_RES_EXITED if user called rdline_quit()
257  *   - Else return RDLINE_RES_SUCCESS.
258  */
259 int rdline_char_in(struct rdline *rdl, char c);
260
261 /**
262  * Read (and edit) a line
263  *
264  * @param rdl
265  *   A pointer to a struct rdline
266  * @param prompt
267  *   The prompt string
268  * @return
269  *   - RDLINE_RES_VALIDATED when the line has been validated.
270  *   - RDLINE_RES_NOT_RUNNING if it is not running.
271  *   - RDLINE_RES_EOF if EOF (ctrl-d on an empty line).
272  *   - RDLINE_RES_EXITED if user called rdline_quit()
273  */
274 int rdline(struct rdline *rdl, const char *prompt);
275
276 /**
277  * write a buffer on rdline file descriptor
278  *
279  * @param rdl
280  *   The rdline descriptor
281  * @param buf
282  *   Pointer to the buffer
283  * @param count
284  *   Number of bytes to write
285  * @return
286  *   On success, the number of bytes written is returned (zero
287  *   indicates nothing was written). On error, -1 is returned, and
288  *   errno is set appropriately
289  */
290 ssize_t rdline_write(const struct rdline *rdl, void *buf, size_t count);
291
292 /**
293  * write on rdline file descriptor according to a format string
294  *
295  * @param rdl
296  *   The rdline descriptor
297  * @param fmt
298  *   The format strings
299  * @return
300  *   Upon successful return, these functions return the number of
301  *   characters printed (not including the trailing '\0' used to end
302  *   output to strings). On error, a negative value is returned.
303  */
304 int rdline_printf(const struct rdline *rdl, const char *fmt, ...);
305
306 /**
307  * write on rdline file descriptor according to a format string
308  *
309  * @param rdl
310  *   The rdline descriptor
311  * @param fmt
312  *   The format strings
313  * @param ap
314  *   Variable argument list
315  * @return
316  *   Upon successful return, these functions return the number of
317  *   characters printed (not including the trailing '\0' used to end
318  *   output to strings). On error, a negative value is returned.
319  */
320 int rdline_vprintf(const struct rdline *rdl, const char *fmt, va_list ap);
321
322 /**
323  * Return the current buffer, terminated by '\0'.
324  *
325  * @param rdl
326  *   A pointer to a struct rdline
327  * @return
328  *   The rdline buffer
329  */
330 const char *rdline_get_buffer(struct rdline *rdl);
331
332 /**
333  * Add the buffer to history.
334  *
335  * @param rdl
336  *   A pointer to a struct rdline
337  * @param buf
338  *   A buffer that is terminated by '\0'
339  * @return
340  *   - 0 on success
341  *   - negative on error
342  */
343 int rdline_add_history(struct rdline *rdl, const char *buf);
344
345 /**
346  * Clear current history
347  *
348  * @param rdl
349  *   A pointer to a struct rdline
350  */
351 void rdline_clear_history(struct rdline *rdl);
352
353 /**
354  * Get the i-th history item
355  *
356  * @param rdl
357  *   A pointer to a struct rdline
358  * @param i
359  *   The index of the history item
360  * @return
361  *   The i-th string of history, or NULL on error.
362  */
363 char *rdline_get_history_item(struct rdline *rdl, unsigned int i);
364
365 #ifndef NO_PAGER
366 /**
367  * Write data asynchronously (using pager if needed)
368  *
369  * If there is enough place to print data on the current page, it is
370  * printed synchronously. Else, a temporary buffer is allocated and
371  * the data is stored in it. When the main rdline is called again, the
372  * pager is flushed before parsing any other commands.
373  *
374  * @param rdl
375  *   The rdline descriptor
376  * @param buf
377  *   Buffer to be sent
378  * @param len
379  *   Length of buffer to be sent
380  * @return
381  *   On success, the number of bytes written is returned (zero
382  *   indicates nothing was written). On error, -1 is returned, and
383  *   errno is set appropriately
384  */
385 ssize_t rdline_asyncpager_write(struct rdline *rdl, void *buf, size_t len);
386
387 /**
388  * Print data asynchronously (using pager if needed)
389  *
390  * If there is enough place to print data on the current page, it is
391  * printed synchronously. Else, a temporary buffer is allocated and
392  * the data is stored in it. When the main rdline is called again, the
393  * pager is flushed before parsing any other commands.
394  *
395  * @param rdl
396  *   The rdline descriptor
397  * @param fmt
398  *   The format strings
399  * @return
400  *   Upon successful return, these functions return the number of
401  *   characters printed (not including the trailing '\0' used to end
402  *   output to strings). On error, a negative value is returned.
403  */
404 int rdline_asyncpager_printf(struct rdline *rdl, const char *fmt, ...);
405
406 /**
407  * Set the callback for the pager
408  *
409  * If there is some data in the pager to be printed, set a callback
410  * function that will be called when all the data will be printed. If
411  * the pager is empty, don't do anything and return -1.
412  * @param rdl
413  *   The rdline descriptor
414  * @return
415  *   - 0 if there is some data in the pager buffer and the callback
416  *     is loaded
417  *   - -1 if there is no data in pager buffer (in this case the callback
418  *     is not called)
419  */
420 int rdline_asyncpager_set_cb(struct rdline *rdl, rdline_asyncpager_cb_t *cb,
421                              void *arg);
422 #endif
423
424
425 #endif /* _RDLINE_H_ */