23b8cb6f65d80e7d39a6a330251be340c8130d04
[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 39
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)(const 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 struct rdline {
116         enum rdline_status status;
117         int fd_in;
118         int fd_out;
119
120         /* rdline bufs */
121         struct cirbuf left;
122         struct cirbuf right;
123         char left_buf[RDLINE_BUF_SIZE+2]; /* reserve 2 chars for the \n\0 */
124         char right_buf[RDLINE_BUF_SIZE];
125
126         char prompt[RDLINE_PROMPT_SIZE];
127
128 #ifndef NO_RDLINE_KILL_BUF
129         char kill_buf[RDLINE_BUF_SIZE];
130         unsigned int kill_size;
131 #endif
132
133 #ifndef NO_RDLINE_HISTORY
134         /* history */
135         struct cirbuf history;
136         char history_buf[RDLINE_HISTORY_BUF_SIZE];
137         int history_cur_line;
138 #endif
139
140         /* callbacks and func pointers */
141         rdline_validate_t *validate;
142         rdline_complete_t *complete;
143         rdline_help_t *help;
144
145         /* vt100 parser */
146         struct cmdline_vt100 vt100;
147
148         /* opaque pointer */
149         void *opaque;
150
151 #ifndef NO_PAGER
152         char *pager_buf; /* buffer used to store paged data */
153         int pager_len; /* total len of buffer */
154         int pager_off; /* offset of next data */
155         int pager_lines; /* number of lines displayed */
156 #endif
157 };
158
159 /**
160  * Init fields for a struct rdline.
161  *
162  * @param rdl A pointer to an uninitialized struct rdline
163  * @param fd_in
164  *   Input file descriptor
165  * @param fd_out
166  *   Output file descriptor
167  * @param validate
168  *   A pointer to the function to execute when the user validates the
169  *   buffer.
170  * @param complete
171  *   A pointer to the function to execute when the user completes the
172  *   buffer.
173  * @param help
174  *   A pointer to the function to execute when the user ask for
175  *   contextual help.
176  */
177 void rdline_init(struct rdline *rdl,
178                  int fd_in, int fd_out,
179                  rdline_validate_t *validate,
180                  rdline_complete_t *complete,
181                  rdline_help_t *help);
182
183
184 /**
185  * Init the current buffer, and display a prompt.
186  *
187  * Also set the rdline status to "running", overriding previous
188  * rdline_stop() or rdline_quit().
189  *
190  * @param rdl
191  *   A pointer to an initialized struct rdline
192  * @param prompt
193  *   A string containing the prompt
194  */
195 void rdline_newline(struct rdline *rdl, const char *prompt);
196
197 /**
198  * Ignore all subsequent received chars.
199  *
200  * @param rdl
201  *   A pointer to a struct rdline
202  */
203 void rdline_stop(struct rdline *rdl);
204
205 /**
206  * Exit from running rdline loop
207  *
208  * Same than rdline_stop() except that next calls to rdline_char_in()
209  * will return RDLINE_RES_EXITED. Hence, any running rdline() function is
210  * interrupted.
211  *
212  * @param rdl
213  *   A pointer to a struct rdline
214  */
215 void rdline_quit(struct rdline *rdl);
216
217 /**
218  * Restart after a call to rdline_stop() or rdline_quit()
219  *
220  * @param rdl
221  *   A pointer to a struct rdline
222  */
223 void rdline_restart(struct rdline *rdl);
224
225 /**
226  * Redisplay the current buffer
227  *
228  * @param rdl
229  *   A pointer to a struct rdline
230  */
231 void rdline_redisplay(struct rdline *rdl);
232
233
234 /* return status for rdline_char_in() */
235 #define RDLINE_RES_SUCCESS       0
236 #define RDLINE_RES_VALIDATED     1
237 #define RDLINE_RES_NOT_RUNNING  -1
238 #define RDLINE_RES_EOF          -2
239 #define RDLINE_RES_EXITED       -3
240
241 /**
242  * Append a char to the readline buffer.
243  *
244  * @param rdl
245  *   A pointer to a struct rdline
246  * @param c
247  *   The character to append
248  * @return
249  *   - RDLINE_RES_VALIDATED when the line has been validated.
250  *   - RDLINE_RES_NOT_RUNNING if it is not running.
251  *   - RDLINE_RES_EOF if EOF (ctrl-d on an empty line).
252  *   - RDLINE_RES_EXITED if user called rdline_quit()
253  *   - Else return RDLINE_RES_SUCCESS.
254  */
255 int rdline_char_in(struct rdline *rdl, char c);
256
257 /**
258  * Read (and edit) a line
259  *
260  * @param rdl
261  *   A pointer to a struct rdline
262  * @param prompt
263  *   The prompt string
264  * @return
265  *   - RDLINE_RES_VALIDATED when the line has been validated.
266  *   - RDLINE_RES_NOT_RUNNING if it is not running.
267  *   - RDLINE_RES_EOF if EOF (ctrl-d on an empty line).
268  *   - RDLINE_RES_EXITED if user called rdline_quit()
269  */
270 int rdline(struct rdline *rdl, const char *prompt);
271
272 /**
273  * write a buffer on rdline file descriptor
274  *
275  * @param rdl
276  *   The rdline descriptor
277  * @param buf
278  *   Pointer to the buffer
279  * @param count
280  *   Number of bytes to write
281  * @return
282  *   On success, the number of bytes written is returned (zero
283  *   indicates nothing was written). On error, -1 is returned, and
284  *   errno is set appropriately
285  */
286 ssize_t rdline_write(const struct rdline *rdl, void *buf, size_t count);
287
288 /**
289  * write on rdline file descriptor according to a format string
290  *
291  * @param rdl
292  *   The rdline descriptor
293  * @param fmt
294  *   The format strings
295  * @return
296  *   Upon successful return, these functions return the number of
297  *   characters printed (not including the trailing '\0' used to end
298  *   output to strings). On error, a negative value is returned.
299  */
300 int rdline_printf(const struct rdline *rdl, const char *fmt, ...);
301
302 /**
303  * write on rdline file descriptor according to a format string
304  *
305  * @param rdl
306  *   The rdline descriptor
307  * @param fmt
308  *   The format strings
309  * @param ap
310  *   Variable argument list
311  * @return
312  *   Upon successful return, these functions return the number of
313  *   characters printed (not including the trailing '\0' used to end
314  *   output to strings). On error, a negative value is returned.
315  */
316 int rdline_vprintf(const struct rdline *rdl, const char *fmt, va_list ap);
317
318 /**
319  * Return the current buffer, terminated by '\0'.
320  *
321  * @param rdl
322  *   A pointer to a struct rdline
323  * @return
324  *   The rdline buffer
325  */
326 const char *rdline_get_buffer(struct rdline *rdl);
327
328 /**
329  * Add the buffer to history.
330  *
331  * @param rdl
332  *   A pointer to a struct rdline
333  * @param buf
334  *   A buffer that is terminated by '\0'
335  * @return
336  *   - 0 on success
337  *   - negative on error
338  */
339 int rdline_add_history(struct rdline *rdl, const char *buf);
340
341 /**
342  * Clear current history
343  *
344  * @param rdl
345  *   A pointer to a struct rdline
346  */
347 void rdline_clear_history(struct rdline *rdl);
348
349 /**
350  * Get the i-th history item
351  *
352  * @param rdl
353  *   A pointer to a struct rdline
354  * @param i
355  *   The index of the history item
356  * @return
357  *   The i-th string of history, or NULL on error.
358  */
359 char *rdline_get_history_item(struct rdline *rdl, unsigned int i);
360
361 #ifndef NO_PAGER
362 /**
363  * Print data asynchronously (using pager if needed)
364  *
365  * If there is enough place to print data on the current page, it is
366  * printed synchronously. Else, a temporary buffer is allocated and
367  * the data is stored in it. When the main rdline is called again, the
368  * pager is flushed before parsing any other commands.
369  *
370  * @param rdl
371  *   The rdline descriptor
372  * @param fmt
373  *   The format strings
374  * @return
375  *   Upon successful return, these functions return the number of
376  *   characters printed (not including the trailing '\0' used to end
377  *   output to strings). On error, a negative value is returned.
378  */
379 int rdline_asyncpager_printf(struct rdline *rdl, const char *fmt, ...);
380 #endif
381
382
383 #endif /* _RDLINE_H_ */