199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright(c) 2010-2014 Intel Corporation. 399a2dd95SBruce Richardson * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org> 499a2dd95SBruce Richardson * All rights reserved. 599a2dd95SBruce Richardson */ 699a2dd95SBruce Richardson 799a2dd95SBruce Richardson #ifndef _RDLINE_H_ 899a2dd95SBruce Richardson #define _RDLINE_H_ 999a2dd95SBruce Richardson 1099a2dd95SBruce Richardson /** 1199a2dd95SBruce Richardson * This file is a small equivalent to the GNU readline library, but it 1299a2dd95SBruce Richardson * was originally designed for small systems, like Atmel AVR 13f8f8dc28SDmitry Kozlyuk * microcontrollers (8 bits). It only uses malloc() on object creation. 1499a2dd95SBruce Richardson * 1599a2dd95SBruce Richardson * Obviously, it does not support as many things as the GNU readline, 1699a2dd95SBruce Richardson * but at least it supports some interesting features like a kill 1799a2dd95SBruce Richardson * buffer and a command history. 1899a2dd95SBruce Richardson * 1999a2dd95SBruce Richardson * It also have a feature that does not have the GNU readline (as far 2099a2dd95SBruce Richardson * as I know): we can have several instances of it running at the same 2199a2dd95SBruce Richardson * time, even on a monothread program, since it works with callbacks. 2299a2dd95SBruce Richardson * 2399a2dd95SBruce Richardson * The lib is designed for a client-side or a server-side use: 2499a2dd95SBruce Richardson * - server-side: the server receives all data from a socket, including 2599a2dd95SBruce Richardson * control chars, like arrows, tabulations, ... The client is 2699a2dd95SBruce Richardson * very simple, it can be a telnet or a minicom through a serial line. 2799a2dd95SBruce Richardson * - client-side: the client receives its data through its stdin for 2899a2dd95SBruce Richardson * instance. 2999a2dd95SBruce Richardson */ 3099a2dd95SBruce Richardson 3199a2dd95SBruce Richardson #include <stdio.h> 32*7ebfedf9SStephen Hemminger 3399a2dd95SBruce Richardson #include <cmdline_cirbuf.h> 3499a2dd95SBruce Richardson #include <cmdline_vt100.h> 3599a2dd95SBruce Richardson 3699a2dd95SBruce Richardson #ifdef __cplusplus 3799a2dd95SBruce Richardson extern "C" { 3899a2dd95SBruce Richardson #endif 3999a2dd95SBruce Richardson 4099a2dd95SBruce Richardson struct rdline; 4199a2dd95SBruce Richardson 4299a2dd95SBruce Richardson typedef int (rdline_write_char_t)(struct rdline *rdl, char); 4399a2dd95SBruce Richardson typedef void (rdline_validate_t)(struct rdline *rdl, 4499a2dd95SBruce Richardson const char *buf, unsigned int size); 4599a2dd95SBruce Richardson typedef int (rdline_complete_t)(struct rdline *rdl, const char *buf, 4699a2dd95SBruce Richardson char *dstbuf, unsigned int dstsize, 4799a2dd95SBruce Richardson int *state); 4899a2dd95SBruce Richardson 4999a2dd95SBruce Richardson /** 50f8f8dc28SDmitry Kozlyuk * Allocate and initialize a new rdline instance. 51f8f8dc28SDmitry Kozlyuk * 5299a2dd95SBruce Richardson * \param write_char The function used by the function to write a character 5399a2dd95SBruce Richardson * \param validate A pointer to the function to execute when the 5499a2dd95SBruce Richardson * user validates the buffer. 5599a2dd95SBruce Richardson * \param complete A pointer to the function to execute when the 5699a2dd95SBruce Richardson * user completes the buffer. 57f8f8dc28SDmitry Kozlyuk * \param opaque User data for use in the callbacks. 58f8f8dc28SDmitry Kozlyuk * 59f8f8dc28SDmitry Kozlyuk * \return New rdline object on success, NULL on failure. 6099a2dd95SBruce Richardson */ 61f8f8dc28SDmitry Kozlyuk struct rdline *rdline_new(rdline_write_char_t *write_char, 6299a2dd95SBruce Richardson rdline_validate_t *validate, 63f8f8dc28SDmitry Kozlyuk rdline_complete_t *complete, 64f8f8dc28SDmitry Kozlyuk void *opaque); 6599a2dd95SBruce Richardson 66f8f8dc28SDmitry Kozlyuk /** 67f8f8dc28SDmitry Kozlyuk * Free an rdline instance. 68f8f8dc28SDmitry Kozlyuk * 69f8f8dc28SDmitry Kozlyuk * \param rdl A pointer to an initialized struct rdline. 70f8f8dc28SDmitry Kozlyuk * If NULL, this function is a no-op. 71f8f8dc28SDmitry Kozlyuk */ 72f8f8dc28SDmitry Kozlyuk void rdline_free(struct rdline *rdl); 7399a2dd95SBruce Richardson 7499a2dd95SBruce Richardson /** 7599a2dd95SBruce Richardson * Init the current buffer, and display a prompt. 7699a2dd95SBruce Richardson * \param rdl A pointer to a struct rdline 7799a2dd95SBruce Richardson * \param prompt A string containing the prompt 7899a2dd95SBruce Richardson */ 7999a2dd95SBruce Richardson void rdline_newline(struct rdline *rdl, const char *prompt); 8099a2dd95SBruce Richardson 8199a2dd95SBruce Richardson /** 8299a2dd95SBruce Richardson * Call it and all received chars will be ignored. 8399a2dd95SBruce Richardson * \param rdl A pointer to a struct rdline 8499a2dd95SBruce Richardson */ 8599a2dd95SBruce Richardson void rdline_stop(struct rdline *rdl); 8699a2dd95SBruce Richardson 8799a2dd95SBruce Richardson /** 8899a2dd95SBruce Richardson * Same than rdline_stop() except that next calls to rdline_char_in() 8999a2dd95SBruce Richardson * will return RDLINE_RES_EXITED. 9099a2dd95SBruce Richardson * \param rdl A pointer to a struct rdline 9199a2dd95SBruce Richardson */ 9299a2dd95SBruce Richardson void rdline_quit(struct rdline *rdl); 9399a2dd95SBruce Richardson 9499a2dd95SBruce Richardson /** 9599a2dd95SBruce Richardson * Restart after a call to rdline_stop() or rdline_quit() 9699a2dd95SBruce Richardson * \param rdl A pointer to a struct rdline 9799a2dd95SBruce Richardson */ 9899a2dd95SBruce Richardson void rdline_restart(struct rdline *rdl); 9999a2dd95SBruce Richardson 10099a2dd95SBruce Richardson /** 10199a2dd95SBruce Richardson * Redisplay the current buffer 10299a2dd95SBruce Richardson * \param rdl A pointer to a struct rdline 10399a2dd95SBruce Richardson */ 10499a2dd95SBruce Richardson void rdline_redisplay(struct rdline *rdl); 10599a2dd95SBruce Richardson 10699a2dd95SBruce Richardson /** 10799a2dd95SBruce Richardson * Reset the current buffer and setup for a new line. 10899a2dd95SBruce Richardson * \param rdl A pointer to a struct rdline 10999a2dd95SBruce Richardson */ 11099a2dd95SBruce Richardson void rdline_reset(struct rdline *rdl); 11199a2dd95SBruce Richardson 11299a2dd95SBruce Richardson 11399a2dd95SBruce Richardson /* return status for rdline_char_in() */ 11499a2dd95SBruce Richardson #define RDLINE_RES_SUCCESS 0 11599a2dd95SBruce Richardson #define RDLINE_RES_VALIDATED 1 11699a2dd95SBruce Richardson #define RDLINE_RES_COMPLETE 2 11799a2dd95SBruce Richardson #define RDLINE_RES_NOT_RUNNING -1 11899a2dd95SBruce Richardson #define RDLINE_RES_EOF -2 11999a2dd95SBruce Richardson #define RDLINE_RES_EXITED -3 12099a2dd95SBruce Richardson 12199a2dd95SBruce Richardson /** 12299a2dd95SBruce Richardson * append a char to the readline buffer. 12399a2dd95SBruce Richardson * Return RDLINE_RES_VALIDATE when the line has been validated. 12499a2dd95SBruce Richardson * Return RDLINE_RES_COMPLETE when the user asked to complete the buffer. 12599a2dd95SBruce Richardson * Return RDLINE_RES_NOT_RUNNING if it is not running. 12699a2dd95SBruce Richardson * Return RDLINE_RES_EOF if EOF (ctrl-d on an empty line). 12799a2dd95SBruce Richardson * Else return RDLINE_RES_SUCCESS. 12899a2dd95SBruce Richardson * XXX error case when the buffer is full ? 12999a2dd95SBruce Richardson * 13099a2dd95SBruce Richardson * \param rdl A pointer to a struct rdline 13199a2dd95SBruce Richardson * \param c The character to append 13299a2dd95SBruce Richardson */ 13399a2dd95SBruce Richardson int rdline_char_in(struct rdline *rdl, char c); 13499a2dd95SBruce Richardson 13599a2dd95SBruce Richardson /** 13699a2dd95SBruce Richardson * Return the current buffer, terminated by '\0'. 13799a2dd95SBruce Richardson * \param rdl A pointer to a struct rdline 13899a2dd95SBruce Richardson */ 13999a2dd95SBruce Richardson const char *rdline_get_buffer(struct rdline *rdl); 14099a2dd95SBruce Richardson 14199a2dd95SBruce Richardson 14299a2dd95SBruce Richardson /** 14399a2dd95SBruce Richardson * Add the buffer to history. 14499a2dd95SBruce Richardson * return < 0 on error. 14599a2dd95SBruce Richardson * \param rdl A pointer to a struct rdline 14699a2dd95SBruce Richardson * \param buf A buffer that is terminated by '\0' 14799a2dd95SBruce Richardson */ 14899a2dd95SBruce Richardson int rdline_add_history(struct rdline *rdl, const char *buf); 14999a2dd95SBruce Richardson 15099a2dd95SBruce Richardson /** 15199a2dd95SBruce Richardson * Clear current history 15299a2dd95SBruce Richardson * \param rdl A pointer to a struct rdline 15399a2dd95SBruce Richardson */ 15499a2dd95SBruce Richardson void rdline_clear_history(struct rdline *rdl); 15599a2dd95SBruce Richardson 15699a2dd95SBruce Richardson /** 15799a2dd95SBruce Richardson * Get the i-th history item 15899a2dd95SBruce Richardson */ 15999a2dd95SBruce Richardson char *rdline_get_history_item(struct rdline *rdl, unsigned int i); 16099a2dd95SBruce Richardson 161f8f8dc28SDmitry Kozlyuk /** 162f8f8dc28SDmitry Kozlyuk * Get maximum history buffer size. 163f8f8dc28SDmitry Kozlyuk */ 164f8f8dc28SDmitry Kozlyuk size_t rdline_get_history_buffer_size(struct rdline *rdl); 165f8f8dc28SDmitry Kozlyuk 166f8f8dc28SDmitry Kozlyuk /** 167f8f8dc28SDmitry Kozlyuk * Get the opaque pointer supplied on struct rdline creation. 168f8f8dc28SDmitry Kozlyuk */ 169f8f8dc28SDmitry Kozlyuk void *rdline_get_opaque(struct rdline *rdl); 170f8f8dc28SDmitry Kozlyuk 17199a2dd95SBruce Richardson #ifdef __cplusplus 17299a2dd95SBruce Richardson } 17399a2dd95SBruce Richardson #endif 17499a2dd95SBruce Richardson 17599a2dd95SBruce Richardson #endif /* _RDLINE_H_ */ 176