1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation. 3 * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org> 4 * All rights reserved. 5 */ 6 7 #ifndef _RDLINE_H_ 8 #define _RDLINE_H_ 9 10 /** 11 * This file is a small equivalent to the GNU readline library, but it 12 * was originally designed for small systems, like Atmel AVR 13 * microcontrollers (8 bits). Indeed, we don't use any malloc that is 14 * sometimes not implemented (or just not recommended) on such 15 * systems. 16 * 17 * Obviously, it does not support as many things as the GNU readline, 18 * but at least it supports some interesting features like a kill 19 * buffer and a command history. 20 * 21 * It also have a feature that does not have the GNU readline (as far 22 * as I know): we can have several instances of it running at the same 23 * time, even on a monothread program, since it works with callbacks. 24 * 25 * The lib is designed for a client-side or a server-side use: 26 * - server-side: the server receives all data from a socket, including 27 * control chars, like arrows, tabulations, ... The client is 28 * very simple, it can be a telnet or a minicom through a serial line. 29 * - client-side: the client receives its data through its stdin for 30 * instance. 31 */ 32 33 #include <stdio.h> 34 #include <cmdline_cirbuf.h> 35 #include <cmdline_vt100.h> 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 /* configuration */ 42 #define RDLINE_BUF_SIZE 512 43 #define RDLINE_PROMPT_SIZE 32 44 #define RDLINE_VT100_BUF_SIZE 8 45 #define RDLINE_HISTORY_BUF_SIZE BUFSIZ 46 #define RDLINE_HISTORY_MAX_LINE 64 47 48 enum rdline_status { 49 RDLINE_INIT, 50 RDLINE_RUNNING, 51 RDLINE_EXITED 52 }; 53 54 struct rdline; 55 56 typedef int (rdline_write_char_t)(struct rdline *rdl, char); 57 typedef void (rdline_validate_t)(struct rdline *rdl, 58 const char *buf, unsigned int size); 59 typedef int (rdline_complete_t)(struct rdline *rdl, const char *buf, 60 char *dstbuf, unsigned int dstsize, 61 int *state); 62 63 struct rdline { 64 enum rdline_status status; 65 /* rdline bufs */ 66 struct cirbuf left; 67 struct cirbuf right; 68 char left_buf[RDLINE_BUF_SIZE+2]; /* reserve 2 chars for the \n\0 */ 69 char right_buf[RDLINE_BUF_SIZE]; 70 71 char prompt[RDLINE_PROMPT_SIZE]; 72 unsigned int prompt_size; 73 74 char kill_buf[RDLINE_BUF_SIZE]; 75 unsigned int kill_size; 76 77 /* history */ 78 struct cirbuf history; 79 char history_buf[RDLINE_HISTORY_BUF_SIZE]; 80 int history_cur_line; 81 82 /* callbacks and func pointers */ 83 rdline_write_char_t *write_char; 84 rdline_validate_t *validate; 85 rdline_complete_t *complete; 86 87 /* vt100 parser */ 88 struct cmdline_vt100 vt100; 89 90 /* opaque pointer */ 91 void *opaque; 92 }; 93 94 /** 95 * Init fields for a struct rdline. Call this only once at the beginning 96 * of your program. 97 * \param rdl A pointer to an uninitialized struct rdline 98 * \param write_char The function used by the function to write a character 99 * \param validate A pointer to the function to execute when the 100 * user validates the buffer. 101 * \param complete A pointer to the function to execute when the 102 * user completes the buffer. 103 */ 104 int rdline_init(struct rdline *rdl, 105 rdline_write_char_t *write_char, 106 rdline_validate_t *validate, 107 rdline_complete_t *complete); 108 109 110 /** 111 * Init the current buffer, and display a prompt. 112 * \param rdl A pointer to a struct rdline 113 * \param prompt A string containing the prompt 114 */ 115 void rdline_newline(struct rdline *rdl, const char *prompt); 116 117 /** 118 * Call it and all received chars will be ignored. 119 * \param rdl A pointer to a struct rdline 120 */ 121 void rdline_stop(struct rdline *rdl); 122 123 /** 124 * Same than rdline_stop() except that next calls to rdline_char_in() 125 * will return RDLINE_RES_EXITED. 126 * \param rdl A pointer to a struct rdline 127 */ 128 void rdline_quit(struct rdline *rdl); 129 130 /** 131 * Restart after a call to rdline_stop() or rdline_quit() 132 * \param rdl A pointer to a struct rdline 133 */ 134 void rdline_restart(struct rdline *rdl); 135 136 /** 137 * Redisplay the current buffer 138 * \param rdl A pointer to a struct rdline 139 */ 140 void rdline_redisplay(struct rdline *rdl); 141 142 /** 143 * Reset the current buffer and setup for a new line. 144 * \param rdl A pointer to a struct rdline 145 */ 146 void rdline_reset(struct rdline *rdl); 147 148 149 /* return status for rdline_char_in() */ 150 #define RDLINE_RES_SUCCESS 0 151 #define RDLINE_RES_VALIDATED 1 152 #define RDLINE_RES_COMPLETE 2 153 #define RDLINE_RES_NOT_RUNNING -1 154 #define RDLINE_RES_EOF -2 155 #define RDLINE_RES_EXITED -3 156 157 /** 158 * append a char to the readline buffer. 159 * Return RDLINE_RES_VALIDATE when the line has been validated. 160 * Return RDLINE_RES_COMPLETE when the user asked to complete the buffer. 161 * Return RDLINE_RES_NOT_RUNNING if it is not running. 162 * Return RDLINE_RES_EOF if EOF (ctrl-d on an empty line). 163 * Else return RDLINE_RES_SUCCESS. 164 * XXX error case when the buffer is full ? 165 * 166 * \param rdl A pointer to a struct rdline 167 * \param c The character to append 168 */ 169 int rdline_char_in(struct rdline *rdl, char c); 170 171 /** 172 * Return the current buffer, terminated by '\0'. 173 * \param rdl A pointer to a struct rdline 174 */ 175 const char *rdline_get_buffer(struct rdline *rdl); 176 177 178 /** 179 * Add the buffer to history. 180 * return < 0 on error. 181 * \param rdl A pointer to a struct rdline 182 * \param buf A buffer that is terminated by '\0' 183 */ 184 int rdline_add_history(struct rdline *rdl, const char *buf); 185 186 /** 187 * Clear current history 188 * \param rdl A pointer to a struct rdline 189 */ 190 void rdline_clear_history(struct rdline *rdl); 191 192 /** 193 * Get the i-th history item 194 */ 195 char *rdline_get_history_item(struct rdline *rdl, unsigned int i); 196 197 #ifdef __cplusplus 198 } 199 #endif 200 201 #endif /* _RDLINE_H_ */ 202