1252884aeSStefan Eßer /* 2252884aeSStefan Eßer * ***************************************************************************** 3252884aeSStefan Eßer * 43aa99676SStefan Eßer * SPDX-License-Identifier: BSD-2-Clause 5252884aeSStefan Eßer * 6a970610aSStefan Eßer * Copyright (c) 2018-2024 Gavin D. Howard and contributors. 7252884aeSStefan Eßer * 8252884aeSStefan Eßer * Redistribution and use in source and binary forms, with or without 9252884aeSStefan Eßer * modification, are permitted provided that the following conditions are met: 10252884aeSStefan Eßer * 11252884aeSStefan Eßer * * Redistributions of source code must retain the above copyright notice, this 12252884aeSStefan Eßer * list of conditions and the following disclaimer. 13252884aeSStefan Eßer * 14252884aeSStefan Eßer * * Redistributions in binary form must reproduce the above copyright notice, 15252884aeSStefan Eßer * this list of conditions and the following disclaimer in the documentation 16252884aeSStefan Eßer * and/or other materials provided with the distribution. 17252884aeSStefan Eßer * 18252884aeSStefan Eßer * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19252884aeSStefan Eßer * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20252884aeSStefan Eßer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21252884aeSStefan Eßer * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22252884aeSStefan Eßer * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23252884aeSStefan Eßer * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24252884aeSStefan Eßer * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25252884aeSStefan Eßer * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26252884aeSStefan Eßer * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27252884aeSStefan Eßer * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28252884aeSStefan Eßer * POSSIBILITY OF SUCH DAMAGE. 29252884aeSStefan Eßer * 30252884aeSStefan Eßer * ***************************************************************************** 31252884aeSStefan Eßer * 32252884aeSStefan Eßer * Adapted from the following: 33252884aeSStefan Eßer * 34252884aeSStefan Eßer * linenoise.c -- guerrilla line editing library against the idea that a 35252884aeSStefan Eßer * line editing lib needs to be 20,000 lines of C code. 36252884aeSStefan Eßer * 37252884aeSStefan Eßer * You can find the original source code at: 38252884aeSStefan Eßer * http://github.com/antirez/linenoise 39252884aeSStefan Eßer * 40252884aeSStefan Eßer * You can find the fork that this code is based on at: 41252884aeSStefan Eßer * https://github.com/rain-1/linenoise-mob 42252884aeSStefan Eßer * 43252884aeSStefan Eßer * ------------------------------------------------------------------------ 44252884aeSStefan Eßer * 45252884aeSStefan Eßer * This code is also under the following license: 46252884aeSStefan Eßer * 47252884aeSStefan Eßer * Copyright (c) 2010-2016, Salvatore Sanfilippo <antirez at gmail dot com> 48252884aeSStefan Eßer * Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com> 49252884aeSStefan Eßer * 50252884aeSStefan Eßer * Redistribution and use in source and binary forms, with or without 51252884aeSStefan Eßer * modification, are permitted provided that the following conditions are 52252884aeSStefan Eßer * met: 53252884aeSStefan Eßer * 54252884aeSStefan Eßer * * Redistributions of source code must retain the above copyright 55252884aeSStefan Eßer * notice, this list of conditions and the following disclaimer. 56252884aeSStefan Eßer * 57252884aeSStefan Eßer * * Redistributions in binary form must reproduce the above copyright 58252884aeSStefan Eßer * notice, this list of conditions and the following disclaimer in the 59252884aeSStefan Eßer * documentation and/or other materials provided with the distribution. 60252884aeSStefan Eßer * 61252884aeSStefan Eßer * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 62252884aeSStefan Eßer * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 63252884aeSStefan Eßer * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 64252884aeSStefan Eßer * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 65252884aeSStefan Eßer * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 66252884aeSStefan Eßer * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 67252884aeSStefan Eßer * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 68252884aeSStefan Eßer * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 69252884aeSStefan Eßer * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 70252884aeSStefan Eßer * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 71252884aeSStefan Eßer * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 72252884aeSStefan Eßer * 73252884aeSStefan Eßer * ***************************************************************************** 74252884aeSStefan Eßer * 75252884aeSStefan Eßer * Definitions for line history. 76252884aeSStefan Eßer * 77252884aeSStefan Eßer */ 78252884aeSStefan Eßer 79252884aeSStefan Eßer #ifndef BC_HISTORY_H 80252884aeSStefan Eßer #define BC_HISTORY_H 81252884aeSStefan Eßer 82d101cdd6SStefan Eßer // These must come before the #if BC_ENABLE_LINE_LIB below because status.h 83d101cdd6SStefan Eßer // defines it. 84d101cdd6SStefan Eßer #include <status.h> 85d101cdd6SStefan Eßer #include <vector.h> 8678bc019dSStefan Eßer 8778bc019dSStefan Eßer #if BC_ENABLE_LINE_LIB 88252884aeSStefan Eßer 89252884aeSStefan Eßer #include <stdbool.h> 9078bc019dSStefan Eßer #include <setjmp.h> 9178bc019dSStefan Eßer #include <signal.h> 9278bc019dSStefan Eßer 9378bc019dSStefan Eßer extern sigjmp_buf bc_history_jmpbuf; 9478bc019dSStefan Eßer extern volatile sig_atomic_t bc_history_inlinelib; 9578bc019dSStefan Eßer 9678bc019dSStefan Eßer #endif // BC_ENABLE_LINE_LIB 9778bc019dSStefan Eßer 9878bc019dSStefan Eßer #if BC_ENABLE_EDITLINE 9978bc019dSStefan Eßer 10078bc019dSStefan Eßer #include <stdio.h> 10178bc019dSStefan Eßer #include <histedit.h> 10278bc019dSStefan Eßer 10378bc019dSStefan Eßer /** 10478bc019dSStefan Eßer * The history struct for editline. 10578bc019dSStefan Eßer */ 10678bc019dSStefan Eßer typedef struct BcHistory 10778bc019dSStefan Eßer { 10878bc019dSStefan Eßer /// A place to store the current line. 10978bc019dSStefan Eßer EditLine* el; 11078bc019dSStefan Eßer 11178bc019dSStefan Eßer /// The history. 11278bc019dSStefan Eßer History* hist; 11378bc019dSStefan Eßer 11478bc019dSStefan Eßer /// Whether the terminal is bad. This is more or less not used. 11578bc019dSStefan Eßer bool badTerm; 11678bc019dSStefan Eßer 11778bc019dSStefan Eßer } BcHistory; 11878bc019dSStefan Eßer 11978bc019dSStefan Eßer // The path to the editrc and its length. 12078bc019dSStefan Eßer extern const char bc_history_editrc[]; 12178bc019dSStefan Eßer extern const size_t bc_history_editrc_len; 12278bc019dSStefan Eßer 123*9b04aee8SStefan Eßer #ifdef __APPLE__ 124*9b04aee8SStefan Eßer 125*9b04aee8SStefan Eßer /** 126*9b04aee8SStefan Eßer * Returns true if the line is a valid line, false otherwise. 127*9b04aee8SStefan Eßer * @param line The line. 128*9b04aee8SStefan Eßer * @param len The length of the line. 129*9b04aee8SStefan Eßer * @return True if the line is valid, false otherwise. 130*9b04aee8SStefan Eßer */ 131*9b04aee8SStefan Eßer #define BC_HISTORY_INVALID_LINE(line, len) \ 132*9b04aee8SStefan Eßer ((line) == NULL && ((len) == -1 || errno == EINTR)) 133*9b04aee8SStefan Eßer 134*9b04aee8SStefan Eßer #else // __APPLE__ 135*9b04aee8SStefan Eßer 136*9b04aee8SStefan Eßer /** 137*9b04aee8SStefan Eßer * Returns true if the line is a valid line, false otherwise. 138*9b04aee8SStefan Eßer * @param line The line. 139*9b04aee8SStefan Eßer * @param len The length of the line. 140*9b04aee8SStefan Eßer * @return True if the line is valid, false otherwise. 141*9b04aee8SStefan Eßer */ 142*9b04aee8SStefan Eßer #define BC_HISTORY_INVALID_LINE(line, len) \ 143*9b04aee8SStefan Eßer ((line) == NULL && (len) == -1 && errno == EINTR) 144*9b04aee8SStefan Eßer 145*9b04aee8SStefan Eßer #endif // __APPLE__ 146*9b04aee8SStefan Eßer 14778bc019dSStefan Eßer #else // BC_ENABLE_EDITLINE 14878bc019dSStefan Eßer 14978bc019dSStefan Eßer #if BC_ENABLE_READLINE 15078bc019dSStefan Eßer 15178bc019dSStefan Eßer #include <stdio.h> 15278bc019dSStefan Eßer #include <readline/readline.h> 15378bc019dSStefan Eßer #include <readline/history.h> 15478bc019dSStefan Eßer 15578bc019dSStefan Eßer /** 15678bc019dSStefan Eßer * The history struct for readline. 15778bc019dSStefan Eßer */ 15878bc019dSStefan Eßer typedef struct BcHistory 15978bc019dSStefan Eßer { 16078bc019dSStefan Eßer /// A place to store the current line. 16178bc019dSStefan Eßer char* line; 16278bc019dSStefan Eßer 16378bc019dSStefan Eßer /// Whether the terminal is bad. This is more or less not used. 16478bc019dSStefan Eßer bool badTerm; 16578bc019dSStefan Eßer 16678bc019dSStefan Eßer } BcHistory; 16778bc019dSStefan Eßer 16878bc019dSStefan Eßer #else // BC_ENABLE_READLINE 16978bc019dSStefan Eßer 17078bc019dSStefan Eßer #if BC_ENABLE_HISTORY 17178bc019dSStefan Eßer 172252884aeSStefan Eßer #include <stddef.h> 173252884aeSStefan Eßer 174252884aeSStefan Eßer #include <signal.h> 175252884aeSStefan Eßer 17644d4804dSStefan Eßer #ifndef _WIN32 177252884aeSStefan Eßer #include <termios.h> 178252884aeSStefan Eßer #include <time.h> 179252884aeSStefan Eßer #include <unistd.h> 180252884aeSStefan Eßer #include <sys/select.h> 18144d4804dSStefan Eßer #else // _WIN32 18244d4804dSStefan Eßer 18344d4804dSStefan Eßer #ifndef WIN32_LEAN_AND_MEAN 18444d4804dSStefan Eßer #define WIN32_LEAN_AND_MEAN 18544d4804dSStefan Eßer #endif // WIN32_LEAN_AND_MEAN 18644d4804dSStefan Eßer 18744d4804dSStefan Eßer #include <Windows.h> 18844d4804dSStefan Eßer #include <io.h> 18944d4804dSStefan Eßer #include <conio.h> 19044d4804dSStefan Eßer 19144d4804dSStefan Eßer #define strncasecmp _strnicmp 19244d4804dSStefan Eßer #define strcasecmp _stricmp 19344d4804dSStefan Eßer 19444d4804dSStefan Eßer #endif // _WIN32 195252884aeSStefan Eßer 196252884aeSStefan Eßer #include <status.h> 197252884aeSStefan Eßer #include <vector.h> 198252884aeSStefan Eßer #include <read.h> 199252884aeSStefan Eßer 20044d4804dSStefan Eßer /// Default columns. 201252884aeSStefan Eßer #define BC_HIST_DEF_COLS (80) 20244d4804dSStefan Eßer 20344d4804dSStefan Eßer /// Max number of history entries. 204252884aeSStefan Eßer #define BC_HIST_MAX_LEN (128) 20544d4804dSStefan Eßer 20644d4804dSStefan Eßer /// Max length of a line. 207252884aeSStefan Eßer #define BC_HIST_MAX_LINE (4095) 20844d4804dSStefan Eßer 20944d4804dSStefan Eßer /// Max size for cursor position buffer. 210252884aeSStefan Eßer #define BC_HIST_SEQ_SIZE (64) 211252884aeSStefan Eßer 21244d4804dSStefan Eßer /** 21344d4804dSStefan Eßer * The number of entries in the history. 21444d4804dSStefan Eßer * @param h The history data. 21544d4804dSStefan Eßer */ 216252884aeSStefan Eßer #define BC_HIST_BUF_LEN(h) ((h)->buf.len - 1) 21744d4804dSStefan Eßer 21844d4804dSStefan Eßer /** 21944d4804dSStefan Eßer * Read n characters into s and check the error. 22044d4804dSStefan Eßer * @param s The buffer to read into. 22144d4804dSStefan Eßer * @param n The number of bytes to read. 22244d4804dSStefan Eßer * @return True if there was an error, false otherwise. 22344d4804dSStefan Eßer */ 224252884aeSStefan Eßer #define BC_HIST_READ(s, n) (bc_history_read((s), (n)) == -1) 225252884aeSStefan Eßer 22644d4804dSStefan Eßer /// Markers for direction when using arrow keys. 227252884aeSStefan Eßer #define BC_HIST_NEXT (false) 228252884aeSStefan Eßer #define BC_HIST_PREV (true) 229252884aeSStefan Eßer 230252884aeSStefan Eßer #if BC_DEBUG_CODE 231252884aeSStefan Eßer 23244d4804dSStefan Eßer // These are just for debugging. 23344d4804dSStefan Eßer 234252884aeSStefan Eßer #define BC_HISTORY_DEBUG_BUF_SIZE (1024) 235252884aeSStefan Eßer 23678bc019dSStefan Eßer // clang-format off 237252884aeSStefan Eßer #define lndebug(...) \ 23878bc019dSStefan Eßer do \ 23978bc019dSStefan Eßer { \ 24078bc019dSStefan Eßer if (bc_history_debug_fp.fd == 0) \ 24178bc019dSStefan Eßer { \ 242252884aeSStefan Eßer bc_history_debug_buf = bc_vm_malloc(BC_HISTORY_DEBUG_BUF_SIZE); \ 243252884aeSStefan Eßer bc_file_init(&bc_history_debug_fp, \ 244252884aeSStefan Eßer open("/tmp/lndebug.txt", O_APPEND), \ 245252884aeSStefan Eßer BC_HISTORY_DEBUG_BUF_SIZE); \ 246252884aeSStefan Eßer bc_file_printf(&bc_history_debug_fp, \ 247252884aeSStefan Eßer "[%zu %zu %zu] p: %d, rows: %d, " \ 248252884aeSStefan Eßer "rpos: %d, max: %zu, oldmax: %d\n", \ 249252884aeSStefan Eßer l->len, l->pos, l->oldcolpos, plen, rows, rpos, \ 250252884aeSStefan Eßer l->maxrows, old_rows); \ 251252884aeSStefan Eßer } \ 252252884aeSStefan Eßer bc_file_printf(&bc_history_debug_fp, ", " __VA_ARGS__); \ 253252884aeSStefan Eßer bc_file_flush(&bc_history_debug_fp); \ 25478bc019dSStefan Eßer } \ 25578bc019dSStefan Eßer while (0) 256252884aeSStefan Eßer #else // BC_DEBUG_CODE 257252884aeSStefan Eßer #define lndebug(fmt, ...) 258252884aeSStefan Eßer #endif // BC_DEBUG_CODE 25978bc019dSStefan Eßer // clang-format on 260252884aeSStefan Eßer 26144d4804dSStefan Eßer /// An enum of useful actions. To understand what these mean, check terminal 26244d4804dSStefan Eßer /// emulators for their shortcuts or the VT100 codes. 26378bc019dSStefan Eßer typedef enum BcHistoryAction 26478bc019dSStefan Eßer { 265252884aeSStefan Eßer BC_ACTION_NULL = 0, 266252884aeSStefan Eßer BC_ACTION_CTRL_A = 1, 267252884aeSStefan Eßer BC_ACTION_CTRL_B = 2, 268252884aeSStefan Eßer BC_ACTION_CTRL_C = 3, 269252884aeSStefan Eßer BC_ACTION_CTRL_D = 4, 270252884aeSStefan Eßer BC_ACTION_CTRL_E = 5, 271252884aeSStefan Eßer BC_ACTION_CTRL_F = 6, 272252884aeSStefan Eßer BC_ACTION_CTRL_H = 8, 273252884aeSStefan Eßer BC_ACTION_TAB = 9, 274252884aeSStefan Eßer BC_ACTION_LINE_FEED = 10, 275252884aeSStefan Eßer BC_ACTION_CTRL_K = 11, 276252884aeSStefan Eßer BC_ACTION_CTRL_L = 12, 277252884aeSStefan Eßer BC_ACTION_ENTER = 13, 278252884aeSStefan Eßer BC_ACTION_CTRL_N = 14, 279252884aeSStefan Eßer BC_ACTION_CTRL_P = 16, 2808c39e252SStefan Eßer BC_ACTION_CTRL_S = 19, 281252884aeSStefan Eßer BC_ACTION_CTRL_T = 20, 282252884aeSStefan Eßer BC_ACTION_CTRL_U = 21, 283252884aeSStefan Eßer BC_ACTION_CTRL_W = 23, 284252884aeSStefan Eßer BC_ACTION_CTRL_Z = 26, 285252884aeSStefan Eßer BC_ACTION_ESC = 27, 28644d4804dSStefan Eßer BC_ACTION_CTRL_BSLASH = 28, 287252884aeSStefan Eßer BC_ACTION_BACKSPACE = 127 288252884aeSStefan Eßer 289252884aeSStefan Eßer } BcHistoryAction; 290252884aeSStefan Eßer 291252884aeSStefan Eßer /** 292252884aeSStefan Eßer * This represents the state during line editing. We pass this state 293252884aeSStefan Eßer * to functions implementing specific editing functionalities. 294252884aeSStefan Eßer */ 29578bc019dSStefan Eßer typedef struct BcHistory 29678bc019dSStefan Eßer { 297252884aeSStefan Eßer /// Edited line buffer. 298252884aeSStefan Eßer BcVec buf; 299252884aeSStefan Eßer 300252884aeSStefan Eßer /// The history. 301252884aeSStefan Eßer BcVec history; 302252884aeSStefan Eßer 3037e5c51e5SStefan Eßer /// Any material printed without a trailing newline. 3047e5c51e5SStefan Eßer BcVec extras; 3057e5c51e5SStefan Eßer 306252884aeSStefan Eßer /// Prompt to display. 307252884aeSStefan Eßer const char* prompt; 308252884aeSStefan Eßer 309252884aeSStefan Eßer /// Prompt length. 310252884aeSStefan Eßer size_t plen; 311252884aeSStefan Eßer 312252884aeSStefan Eßer /// Prompt column length. 313252884aeSStefan Eßer size_t pcol; 314252884aeSStefan Eßer 315252884aeSStefan Eßer /// Current cursor position. 316252884aeSStefan Eßer size_t pos; 317252884aeSStefan Eßer 318252884aeSStefan Eßer /// Previous refresh cursor column position. 319252884aeSStefan Eßer size_t oldcolpos; 320252884aeSStefan Eßer 321252884aeSStefan Eßer /// Number of columns in terminal. 322252884aeSStefan Eßer size_t cols; 323252884aeSStefan Eßer 324252884aeSStefan Eßer /// The history index we are currently editing. 325252884aeSStefan Eßer size_t idx; 326252884aeSStefan Eßer 32744d4804dSStefan Eßer #ifndef _WIN32 328252884aeSStefan Eßer /// The original terminal state. 329252884aeSStefan Eßer struct termios orig_termios; 33044d4804dSStefan Eßer #else // _WIN32 331d43fa8efSStefan Eßer /// The original input console mode. 332d43fa8efSStefan Eßer DWORD orig_in; 333d43fa8efSStefan Eßer 334d43fa8efSStefan Eßer /// The original output console mode. 335d43fa8efSStefan Eßer DWORD orig_out; 33644d4804dSStefan Eßer #endif // _WIN32 337252884aeSStefan Eßer 33844d4804dSStefan Eßer /// These next two are here because pahole found a 4 byte hole here. 339252884aeSStefan Eßer 340252884aeSStefan Eßer /// Whether we are in rawmode. 341252884aeSStefan Eßer bool rawMode; 342252884aeSStefan Eßer 343252884aeSStefan Eßer /// Whether the terminal is bad. 344252884aeSStefan Eßer bool badTerm; 345252884aeSStefan Eßer 34644d4804dSStefan Eßer #ifndef _WIN32 347252884aeSStefan Eßer /// This is to check if stdin has more data. 348252884aeSStefan Eßer fd_set rdset; 349252884aeSStefan Eßer 350252884aeSStefan Eßer /// This is to check if stdin has more data. 351252884aeSStefan Eßer struct timespec ts; 352252884aeSStefan Eßer 353252884aeSStefan Eßer /// This is to check if stdin has more data. 354252884aeSStefan Eßer sigset_t sigmask; 35544d4804dSStefan Eßer #endif // _WIN32 356252884aeSStefan Eßer 357252884aeSStefan Eßer } BcHistory; 358252884aeSStefan Eßer 35944d4804dSStefan Eßer /** 36044d4804dSStefan Eßer * Frees strings used by history. 36144d4804dSStefan Eßer * @param str The string to free. 36244d4804dSStefan Eßer */ 36378bc019dSStefan Eßer void 36478bc019dSStefan Eßer bc_history_string_free(void* str); 36544d4804dSStefan Eßer 36644d4804dSStefan Eßer // A list of terminals that don't work. 367252884aeSStefan Eßer extern const char* bc_history_bad_terms[]; 36844d4804dSStefan Eßer 36944d4804dSStefan Eßer // A tab in history and its length. 370252884aeSStefan Eßer extern const char bc_history_tab[]; 371252884aeSStefan Eßer extern const size_t bc_history_tab_len; 37244d4804dSStefan Eßer 37344d4804dSStefan Eßer // A ctrl+c string. 374252884aeSStefan Eßer extern const char bc_history_ctrlc[]; 37544d4804dSStefan Eßer 37644d4804dSStefan Eßer // UTF-8 data arrays. 377252884aeSStefan Eßer extern const uint32_t bc_history_wchars[][2]; 378252884aeSStefan Eßer extern const size_t bc_history_wchars_len; 379252884aeSStefan Eßer extern const uint32_t bc_history_combo_chars[]; 380252884aeSStefan Eßer extern const size_t bc_history_combo_chars_len; 38144d4804dSStefan Eßer 382252884aeSStefan Eßer #if BC_DEBUG_CODE 38344d4804dSStefan Eßer 38444d4804dSStefan Eßer // Debug data. 385252884aeSStefan Eßer extern BcFile bc_history_debug_fp; 386252884aeSStefan Eßer extern char* bc_history_debug_buf; 38744d4804dSStefan Eßer 38844d4804dSStefan Eßer /** 38944d4804dSStefan Eßer * A function to print keycodes for debugging. 39044d4804dSStefan Eßer * @param h The history data. 39144d4804dSStefan Eßer */ 39278bc019dSStefan Eßer void 39378bc019dSStefan Eßer bc_history_printKeyCodes(BcHistory* h); 39444d4804dSStefan Eßer 395252884aeSStefan Eßer #endif // BC_DEBUG_CODE 396252884aeSStefan Eßer 397252884aeSStefan Eßer #endif // BC_ENABLE_HISTORY 398252884aeSStefan Eßer 39978bc019dSStefan Eßer #endif // BC_ENABLE_READLINE 40078bc019dSStefan Eßer 40178bc019dSStefan Eßer #endif // BC_ENABLE_EDITLINE 40278bc019dSStefan Eßer 40378bc019dSStefan Eßer #if BC_ENABLE_HISTORY 40478bc019dSStefan Eßer 40578bc019dSStefan Eßer /** 40678bc019dSStefan Eßer * Get a line from stdin using history. This returns a status because I don't 40778bc019dSStefan Eßer * want to throw errors while the terminal is in raw mode. 40878bc019dSStefan Eßer * @param h The history data. 40978bc019dSStefan Eßer * @param vec A vector to put the line into. 41078bc019dSStefan Eßer * @param prompt The prompt to display, if desired. 41178bc019dSStefan Eßer * @return A status indicating an error, if any. Returning a status here 41278bc019dSStefan Eßer * is better because if we throw an error out of history, we 41378bc019dSStefan Eßer * leave the terminal in raw mode or in some other half-baked 41478bc019dSStefan Eßer * state. 41578bc019dSStefan Eßer */ 41678bc019dSStefan Eßer BcStatus 41778bc019dSStefan Eßer bc_history_line(BcHistory* h, BcVec* vec, const char* prompt); 41878bc019dSStefan Eßer 41978bc019dSStefan Eßer /** 42078bc019dSStefan Eßer * Initialize history data. 42178bc019dSStefan Eßer * @param h The struct to initialize. 42278bc019dSStefan Eßer */ 42378bc019dSStefan Eßer void 42478bc019dSStefan Eßer bc_history_init(BcHistory* h); 42578bc019dSStefan Eßer 42678bc019dSStefan Eßer /** 42778bc019dSStefan Eßer * Free history data (and recook the terminal). 42878bc019dSStefan Eßer * @param h The struct to free. 42978bc019dSStefan Eßer */ 43078bc019dSStefan Eßer void 43178bc019dSStefan Eßer bc_history_free(BcHistory* h); 43278bc019dSStefan Eßer 43378bc019dSStefan Eßer #endif // BC_ENABLE_HISTORY 43478bc019dSStefan Eßer 435252884aeSStefan Eßer #endif // BC_HISTORY_H 436