xref: /aosp_15_r20/external/bc/include/history.h (revision 5a6e848804d15c18a0125914844ee4eb0bda4fcf)
1*5a6e8488SAndroid Build Coastguard Worker /*
2*5a6e8488SAndroid Build Coastguard Worker  * *****************************************************************************
3*5a6e8488SAndroid Build Coastguard Worker  *
4*5a6e8488SAndroid Build Coastguard Worker  * SPDX-License-Identifier: BSD-2-Clause
5*5a6e8488SAndroid Build Coastguard Worker  *
6*5a6e8488SAndroid Build Coastguard Worker  * Copyright (c) 2018-2024 Gavin D. Howard and contributors.
7*5a6e8488SAndroid Build Coastguard Worker  *
8*5a6e8488SAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
9*5a6e8488SAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions are met:
10*5a6e8488SAndroid Build Coastguard Worker  *
11*5a6e8488SAndroid Build Coastguard Worker  * * Redistributions of source code must retain the above copyright notice, this
12*5a6e8488SAndroid Build Coastguard Worker  *   list of conditions and the following disclaimer.
13*5a6e8488SAndroid Build Coastguard Worker  *
14*5a6e8488SAndroid Build Coastguard Worker  * * Redistributions in binary form must reproduce the above copyright notice,
15*5a6e8488SAndroid Build Coastguard Worker  *   this list of conditions and the following disclaimer in the documentation
16*5a6e8488SAndroid Build Coastguard Worker  *   and/or other materials provided with the distribution.
17*5a6e8488SAndroid Build Coastguard Worker  *
18*5a6e8488SAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19*5a6e8488SAndroid Build Coastguard Worker  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*5a6e8488SAndroid Build Coastguard Worker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*5a6e8488SAndroid Build Coastguard Worker  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22*5a6e8488SAndroid Build Coastguard Worker  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23*5a6e8488SAndroid Build Coastguard Worker  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24*5a6e8488SAndroid Build Coastguard Worker  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25*5a6e8488SAndroid Build Coastguard Worker  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26*5a6e8488SAndroid Build Coastguard Worker  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27*5a6e8488SAndroid Build Coastguard Worker  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28*5a6e8488SAndroid Build Coastguard Worker  * POSSIBILITY OF SUCH DAMAGE.
29*5a6e8488SAndroid Build Coastguard Worker  *
30*5a6e8488SAndroid Build Coastguard Worker  * *****************************************************************************
31*5a6e8488SAndroid Build Coastguard Worker  *
32*5a6e8488SAndroid Build Coastguard Worker  * Adapted from the following:
33*5a6e8488SAndroid Build Coastguard Worker  *
34*5a6e8488SAndroid Build Coastguard Worker  * linenoise.c -- guerrilla line editing library against the idea that a
35*5a6e8488SAndroid Build Coastguard Worker  * line editing lib needs to be 20,000 lines of C code.
36*5a6e8488SAndroid Build Coastguard Worker  *
37*5a6e8488SAndroid Build Coastguard Worker  * You can find the original source code at:
38*5a6e8488SAndroid Build Coastguard Worker  *   http://github.com/antirez/linenoise
39*5a6e8488SAndroid Build Coastguard Worker  *
40*5a6e8488SAndroid Build Coastguard Worker  * You can find the fork that this code is based on at:
41*5a6e8488SAndroid Build Coastguard Worker  *   https://github.com/rain-1/linenoise-mob
42*5a6e8488SAndroid Build Coastguard Worker  *
43*5a6e8488SAndroid Build Coastguard Worker  * ------------------------------------------------------------------------
44*5a6e8488SAndroid Build Coastguard Worker  *
45*5a6e8488SAndroid Build Coastguard Worker  * This code is also under the following license:
46*5a6e8488SAndroid Build Coastguard Worker  *
47*5a6e8488SAndroid Build Coastguard Worker  * Copyright (c) 2010-2016, Salvatore Sanfilippo <antirez at gmail dot com>
48*5a6e8488SAndroid Build Coastguard Worker  * Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
49*5a6e8488SAndroid Build Coastguard Worker  *
50*5a6e8488SAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
51*5a6e8488SAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions are
52*5a6e8488SAndroid Build Coastguard Worker  * met:
53*5a6e8488SAndroid Build Coastguard Worker  *
54*5a6e8488SAndroid Build Coastguard Worker  *  *  Redistributions of source code must retain the above copyright
55*5a6e8488SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer.
56*5a6e8488SAndroid Build Coastguard Worker  *
57*5a6e8488SAndroid Build Coastguard Worker  *  *  Redistributions in binary form must reproduce the above copyright
58*5a6e8488SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer in the
59*5a6e8488SAndroid Build Coastguard Worker  *     documentation and/or other materials provided with the distribution.
60*5a6e8488SAndroid Build Coastguard Worker  *
61*5a6e8488SAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
62*5a6e8488SAndroid Build Coastguard Worker  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
63*5a6e8488SAndroid Build Coastguard Worker  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
64*5a6e8488SAndroid Build Coastguard Worker  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
65*5a6e8488SAndroid Build Coastguard Worker  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
66*5a6e8488SAndroid Build Coastguard Worker  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
67*5a6e8488SAndroid Build Coastguard Worker  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
68*5a6e8488SAndroid Build Coastguard Worker  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
69*5a6e8488SAndroid Build Coastguard Worker  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70*5a6e8488SAndroid Build Coastguard Worker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
71*5a6e8488SAndroid Build Coastguard Worker  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72*5a6e8488SAndroid Build Coastguard Worker  *
73*5a6e8488SAndroid Build Coastguard Worker  * *****************************************************************************
74*5a6e8488SAndroid Build Coastguard Worker  *
75*5a6e8488SAndroid Build Coastguard Worker  * Definitions for line history.
76*5a6e8488SAndroid Build Coastguard Worker  *
77*5a6e8488SAndroid Build Coastguard Worker  */
78*5a6e8488SAndroid Build Coastguard Worker 
79*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_HISTORY_H
80*5a6e8488SAndroid Build Coastguard Worker #define BC_HISTORY_H
81*5a6e8488SAndroid Build Coastguard Worker 
82*5a6e8488SAndroid Build Coastguard Worker // These must come before the #if BC_ENABLE_LINE_LIB below because status.h
83*5a6e8488SAndroid Build Coastguard Worker // defines it.
84*5a6e8488SAndroid Build Coastguard Worker #include <status.h>
85*5a6e8488SAndroid Build Coastguard Worker #include <vector.h>
86*5a6e8488SAndroid Build Coastguard Worker 
87*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_LINE_LIB
88*5a6e8488SAndroid Build Coastguard Worker 
89*5a6e8488SAndroid Build Coastguard Worker #include <stdbool.h>
90*5a6e8488SAndroid Build Coastguard Worker #include <setjmp.h>
91*5a6e8488SAndroid Build Coastguard Worker #include <signal.h>
92*5a6e8488SAndroid Build Coastguard Worker 
93*5a6e8488SAndroid Build Coastguard Worker extern sigjmp_buf bc_history_jmpbuf;
94*5a6e8488SAndroid Build Coastguard Worker extern volatile sig_atomic_t bc_history_inlinelib;
95*5a6e8488SAndroid Build Coastguard Worker 
96*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_LINE_LIB
97*5a6e8488SAndroid Build Coastguard Worker 
98*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EDITLINE
99*5a6e8488SAndroid Build Coastguard Worker 
100*5a6e8488SAndroid Build Coastguard Worker #include <stdio.h>
101*5a6e8488SAndroid Build Coastguard Worker #include <histedit.h>
102*5a6e8488SAndroid Build Coastguard Worker 
103*5a6e8488SAndroid Build Coastguard Worker /**
104*5a6e8488SAndroid Build Coastguard Worker  * The history struct for editline.
105*5a6e8488SAndroid Build Coastguard Worker  */
106*5a6e8488SAndroid Build Coastguard Worker typedef struct BcHistory
107*5a6e8488SAndroid Build Coastguard Worker {
108*5a6e8488SAndroid Build Coastguard Worker 	/// A place to store the current line.
109*5a6e8488SAndroid Build Coastguard Worker 	EditLine* el;
110*5a6e8488SAndroid Build Coastguard Worker 
111*5a6e8488SAndroid Build Coastguard Worker 	/// The history.
112*5a6e8488SAndroid Build Coastguard Worker 	History* hist;
113*5a6e8488SAndroid Build Coastguard Worker 
114*5a6e8488SAndroid Build Coastguard Worker 	/// Whether the terminal is bad. This is more or less not used.
115*5a6e8488SAndroid Build Coastguard Worker 	bool badTerm;
116*5a6e8488SAndroid Build Coastguard Worker 
117*5a6e8488SAndroid Build Coastguard Worker } BcHistory;
118*5a6e8488SAndroid Build Coastguard Worker 
119*5a6e8488SAndroid Build Coastguard Worker // The path to the editrc and its length.
120*5a6e8488SAndroid Build Coastguard Worker extern const char bc_history_editrc[];
121*5a6e8488SAndroid Build Coastguard Worker extern const size_t bc_history_editrc_len;
122*5a6e8488SAndroid Build Coastguard Worker 
123*5a6e8488SAndroid Build Coastguard Worker #ifdef __APPLE__
124*5a6e8488SAndroid Build Coastguard Worker 
125*5a6e8488SAndroid Build Coastguard Worker /**
126*5a6e8488SAndroid Build Coastguard Worker  * Returns true if the line is a valid line, false otherwise.
127*5a6e8488SAndroid Build Coastguard Worker  * @param line  The line.
128*5a6e8488SAndroid Build Coastguard Worker  * @param len   The length of the line.
129*5a6e8488SAndroid Build Coastguard Worker  * @return      True if the line is valid, false otherwise.
130*5a6e8488SAndroid Build Coastguard Worker  */
131*5a6e8488SAndroid Build Coastguard Worker #define BC_HISTORY_INVALID_LINE(line, len) \
132*5a6e8488SAndroid Build Coastguard Worker 	((line) == NULL && ((len) == -1 || errno == EINTR))
133*5a6e8488SAndroid Build Coastguard Worker 
134*5a6e8488SAndroid Build Coastguard Worker #else // __APPLE__
135*5a6e8488SAndroid Build Coastguard Worker 
136*5a6e8488SAndroid Build Coastguard Worker /**
137*5a6e8488SAndroid Build Coastguard Worker  * Returns true if the line is a valid line, false otherwise.
138*5a6e8488SAndroid Build Coastguard Worker  * @param line  The line.
139*5a6e8488SAndroid Build Coastguard Worker  * @param len   The length of the line.
140*5a6e8488SAndroid Build Coastguard Worker  * @return      True if the line is valid, false otherwise.
141*5a6e8488SAndroid Build Coastguard Worker  */
142*5a6e8488SAndroid Build Coastguard Worker #define BC_HISTORY_INVALID_LINE(line, len) \
143*5a6e8488SAndroid Build Coastguard Worker 	((line) == NULL && (len) == -1 && errno == EINTR)
144*5a6e8488SAndroid Build Coastguard Worker 
145*5a6e8488SAndroid Build Coastguard Worker #endif // __APPLE__
146*5a6e8488SAndroid Build Coastguard Worker 
147*5a6e8488SAndroid Build Coastguard Worker #else // BC_ENABLE_EDITLINE
148*5a6e8488SAndroid Build Coastguard Worker 
149*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_READLINE
150*5a6e8488SAndroid Build Coastguard Worker 
151*5a6e8488SAndroid Build Coastguard Worker #include <stdio.h>
152*5a6e8488SAndroid Build Coastguard Worker #include <readline/readline.h>
153*5a6e8488SAndroid Build Coastguard Worker #include <readline/history.h>
154*5a6e8488SAndroid Build Coastguard Worker 
155*5a6e8488SAndroid Build Coastguard Worker /**
156*5a6e8488SAndroid Build Coastguard Worker  * The history struct for readline.
157*5a6e8488SAndroid Build Coastguard Worker  */
158*5a6e8488SAndroid Build Coastguard Worker typedef struct BcHistory
159*5a6e8488SAndroid Build Coastguard Worker {
160*5a6e8488SAndroid Build Coastguard Worker 	/// A place to store the current line.
161*5a6e8488SAndroid Build Coastguard Worker 	char* line;
162*5a6e8488SAndroid Build Coastguard Worker 
163*5a6e8488SAndroid Build Coastguard Worker 	/// Whether the terminal is bad. This is more or less not used.
164*5a6e8488SAndroid Build Coastguard Worker 	bool badTerm;
165*5a6e8488SAndroid Build Coastguard Worker 
166*5a6e8488SAndroid Build Coastguard Worker } BcHistory;
167*5a6e8488SAndroid Build Coastguard Worker 
168*5a6e8488SAndroid Build Coastguard Worker #else // BC_ENABLE_READLINE
169*5a6e8488SAndroid Build Coastguard Worker 
170*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_HISTORY
171*5a6e8488SAndroid Build Coastguard Worker 
172*5a6e8488SAndroid Build Coastguard Worker #include <stddef.h>
173*5a6e8488SAndroid Build Coastguard Worker 
174*5a6e8488SAndroid Build Coastguard Worker #include <signal.h>
175*5a6e8488SAndroid Build Coastguard Worker 
176*5a6e8488SAndroid Build Coastguard Worker #ifndef _WIN32
177*5a6e8488SAndroid Build Coastguard Worker #include <termios.h>
178*5a6e8488SAndroid Build Coastguard Worker #include <time.h>
179*5a6e8488SAndroid Build Coastguard Worker #include <unistd.h>
180*5a6e8488SAndroid Build Coastguard Worker #include <sys/select.h>
181*5a6e8488SAndroid Build Coastguard Worker #else // _WIN32
182*5a6e8488SAndroid Build Coastguard Worker 
183*5a6e8488SAndroid Build Coastguard Worker #ifndef WIN32_LEAN_AND_MEAN
184*5a6e8488SAndroid Build Coastguard Worker #define WIN32_LEAN_AND_MEAN
185*5a6e8488SAndroid Build Coastguard Worker #endif // WIN32_LEAN_AND_MEAN
186*5a6e8488SAndroid Build Coastguard Worker 
187*5a6e8488SAndroid Build Coastguard Worker #include <Windows.h>
188*5a6e8488SAndroid Build Coastguard Worker #include <io.h>
189*5a6e8488SAndroid Build Coastguard Worker #include <conio.h>
190*5a6e8488SAndroid Build Coastguard Worker 
191*5a6e8488SAndroid Build Coastguard Worker #define strncasecmp _strnicmp
192*5a6e8488SAndroid Build Coastguard Worker #define strcasecmp _stricmp
193*5a6e8488SAndroid Build Coastguard Worker 
194*5a6e8488SAndroid Build Coastguard Worker #endif // _WIN32
195*5a6e8488SAndroid Build Coastguard Worker 
196*5a6e8488SAndroid Build Coastguard Worker #include <status.h>
197*5a6e8488SAndroid Build Coastguard Worker #include <vector.h>
198*5a6e8488SAndroid Build Coastguard Worker #include <read.h>
199*5a6e8488SAndroid Build Coastguard Worker 
200*5a6e8488SAndroid Build Coastguard Worker /// Default columns.
201*5a6e8488SAndroid Build Coastguard Worker #define BC_HIST_DEF_COLS (80)
202*5a6e8488SAndroid Build Coastguard Worker 
203*5a6e8488SAndroid Build Coastguard Worker /// Max number of history entries.
204*5a6e8488SAndroid Build Coastguard Worker #define BC_HIST_MAX_LEN (128)
205*5a6e8488SAndroid Build Coastguard Worker 
206*5a6e8488SAndroid Build Coastguard Worker /// Max length of a line.
207*5a6e8488SAndroid Build Coastguard Worker #define BC_HIST_MAX_LINE (4095)
208*5a6e8488SAndroid Build Coastguard Worker 
209*5a6e8488SAndroid Build Coastguard Worker /// Max size for cursor position buffer.
210*5a6e8488SAndroid Build Coastguard Worker #define BC_HIST_SEQ_SIZE (64)
211*5a6e8488SAndroid Build Coastguard Worker 
212*5a6e8488SAndroid Build Coastguard Worker /**
213*5a6e8488SAndroid Build Coastguard Worker  * The number of entries in the history.
214*5a6e8488SAndroid Build Coastguard Worker  * @param h  The history data.
215*5a6e8488SAndroid Build Coastguard Worker  */
216*5a6e8488SAndroid Build Coastguard Worker #define BC_HIST_BUF_LEN(h) ((h)->buf.len - 1)
217*5a6e8488SAndroid Build Coastguard Worker 
218*5a6e8488SAndroid Build Coastguard Worker /**
219*5a6e8488SAndroid Build Coastguard Worker  * Read n characters into s and check the error.
220*5a6e8488SAndroid Build Coastguard Worker  * @param s  The buffer to read into.
221*5a6e8488SAndroid Build Coastguard Worker  * @param n  The number of bytes to read.
222*5a6e8488SAndroid Build Coastguard Worker  * @return   True if there was an error, false otherwise.
223*5a6e8488SAndroid Build Coastguard Worker  */
224*5a6e8488SAndroid Build Coastguard Worker #define BC_HIST_READ(s, n) (bc_history_read((s), (n)) == -1)
225*5a6e8488SAndroid Build Coastguard Worker 
226*5a6e8488SAndroid Build Coastguard Worker /// Markers for direction when using arrow keys.
227*5a6e8488SAndroid Build Coastguard Worker #define BC_HIST_NEXT (false)
228*5a6e8488SAndroid Build Coastguard Worker #define BC_HIST_PREV (true)
229*5a6e8488SAndroid Build Coastguard Worker 
230*5a6e8488SAndroid Build Coastguard Worker #if BC_DEBUG_CODE
231*5a6e8488SAndroid Build Coastguard Worker 
232*5a6e8488SAndroid Build Coastguard Worker // These are just for debugging.
233*5a6e8488SAndroid Build Coastguard Worker 
234*5a6e8488SAndroid Build Coastguard Worker #define BC_HISTORY_DEBUG_BUF_SIZE (1024)
235*5a6e8488SAndroid Build Coastguard Worker 
236*5a6e8488SAndroid Build Coastguard Worker // clang-format off
237*5a6e8488SAndroid Build Coastguard Worker #define lndebug(...)                                                        \
238*5a6e8488SAndroid Build Coastguard Worker 	do                                                                      \
239*5a6e8488SAndroid Build Coastguard Worker 	{                                                                       \
240*5a6e8488SAndroid Build Coastguard Worker 		if (bc_history_debug_fp.fd == 0)                                    \
241*5a6e8488SAndroid Build Coastguard Worker 		{                                                                   \
242*5a6e8488SAndroid Build Coastguard Worker 			bc_history_debug_buf = bc_vm_malloc(BC_HISTORY_DEBUG_BUF_SIZE); \
243*5a6e8488SAndroid Build Coastguard Worker 			bc_file_init(&bc_history_debug_fp,                              \
244*5a6e8488SAndroid Build Coastguard Worker 			             open("/tmp/lndebug.txt", O_APPEND),                \
245*5a6e8488SAndroid Build Coastguard Worker 		                 BC_HISTORY_DEBUG_BUF_SIZE);                        \
246*5a6e8488SAndroid Build Coastguard Worker 			bc_file_printf(&bc_history_debug_fp,                            \
247*5a6e8488SAndroid Build Coastguard Worker 			       "[%zu %zu %zu] p: %d, rows: %d, "                        \
248*5a6e8488SAndroid Build Coastguard Worker 			       "rpos: %d, max: %zu, oldmax: %d\n",                      \
249*5a6e8488SAndroid Build Coastguard Worker 			       l->len, l->pos, l->oldcolpos, plen, rows, rpos,          \
250*5a6e8488SAndroid Build Coastguard Worker 			       l->maxrows, old_rows);                                   \
251*5a6e8488SAndroid Build Coastguard Worker 		}                                                                   \
252*5a6e8488SAndroid Build Coastguard Worker 		bc_file_printf(&bc_history_debug_fp, ", " __VA_ARGS__);             \
253*5a6e8488SAndroid Build Coastguard Worker 		bc_file_flush(&bc_history_debug_fp);                                \
254*5a6e8488SAndroid Build Coastguard Worker 	}                                                                       \
255*5a6e8488SAndroid Build Coastguard Worker 	while (0)
256*5a6e8488SAndroid Build Coastguard Worker #else // BC_DEBUG_CODE
257*5a6e8488SAndroid Build Coastguard Worker #define lndebug(fmt, ...)
258*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEBUG_CODE
259*5a6e8488SAndroid Build Coastguard Worker // clang-format on
260*5a6e8488SAndroid Build Coastguard Worker 
261*5a6e8488SAndroid Build Coastguard Worker /// An enum of useful actions. To understand what these mean, check terminal
262*5a6e8488SAndroid Build Coastguard Worker /// emulators for their shortcuts or the VT100 codes.
263*5a6e8488SAndroid Build Coastguard Worker typedef enum BcHistoryAction
264*5a6e8488SAndroid Build Coastguard Worker {
265*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_NULL = 0,
266*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_CTRL_A = 1,
267*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_CTRL_B = 2,
268*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_CTRL_C = 3,
269*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_CTRL_D = 4,
270*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_CTRL_E = 5,
271*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_CTRL_F = 6,
272*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_CTRL_H = 8,
273*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_TAB = 9,
274*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_LINE_FEED = 10,
275*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_CTRL_K = 11,
276*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_CTRL_L = 12,
277*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_ENTER = 13,
278*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_CTRL_N = 14,
279*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_CTRL_P = 16,
280*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_CTRL_S = 19,
281*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_CTRL_T = 20,
282*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_CTRL_U = 21,
283*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_CTRL_W = 23,
284*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_CTRL_Z = 26,
285*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_ESC = 27,
286*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_CTRL_BSLASH = 28,
287*5a6e8488SAndroid Build Coastguard Worker 	BC_ACTION_BACKSPACE = 127
288*5a6e8488SAndroid Build Coastguard Worker 
289*5a6e8488SAndroid Build Coastguard Worker } BcHistoryAction;
290*5a6e8488SAndroid Build Coastguard Worker 
291*5a6e8488SAndroid Build Coastguard Worker /**
292*5a6e8488SAndroid Build Coastguard Worker  * This represents the state during line editing. We pass this state
293*5a6e8488SAndroid Build Coastguard Worker  * to functions implementing specific editing functionalities.
294*5a6e8488SAndroid Build Coastguard Worker  */
295*5a6e8488SAndroid Build Coastguard Worker typedef struct BcHistory
296*5a6e8488SAndroid Build Coastguard Worker {
297*5a6e8488SAndroid Build Coastguard Worker 	/// Edited line buffer.
298*5a6e8488SAndroid Build Coastguard Worker 	BcVec buf;
299*5a6e8488SAndroid Build Coastguard Worker 
300*5a6e8488SAndroid Build Coastguard Worker 	/// The history.
301*5a6e8488SAndroid Build Coastguard Worker 	BcVec history;
302*5a6e8488SAndroid Build Coastguard Worker 
303*5a6e8488SAndroid Build Coastguard Worker 	/// Any material printed without a trailing newline.
304*5a6e8488SAndroid Build Coastguard Worker 	BcVec extras;
305*5a6e8488SAndroid Build Coastguard Worker 
306*5a6e8488SAndroid Build Coastguard Worker 	/// Prompt to display.
307*5a6e8488SAndroid Build Coastguard Worker 	const char* prompt;
308*5a6e8488SAndroid Build Coastguard Worker 
309*5a6e8488SAndroid Build Coastguard Worker 	/// Prompt length.
310*5a6e8488SAndroid Build Coastguard Worker 	size_t plen;
311*5a6e8488SAndroid Build Coastguard Worker 
312*5a6e8488SAndroid Build Coastguard Worker 	/// Prompt column length.
313*5a6e8488SAndroid Build Coastguard Worker 	size_t pcol;
314*5a6e8488SAndroid Build Coastguard Worker 
315*5a6e8488SAndroid Build Coastguard Worker 	/// Current cursor position.
316*5a6e8488SAndroid Build Coastguard Worker 	size_t pos;
317*5a6e8488SAndroid Build Coastguard Worker 
318*5a6e8488SAndroid Build Coastguard Worker 	/// Previous refresh cursor column position.
319*5a6e8488SAndroid Build Coastguard Worker 	size_t oldcolpos;
320*5a6e8488SAndroid Build Coastguard Worker 
321*5a6e8488SAndroid Build Coastguard Worker 	/// Number of columns in terminal.
322*5a6e8488SAndroid Build Coastguard Worker 	size_t cols;
323*5a6e8488SAndroid Build Coastguard Worker 
324*5a6e8488SAndroid Build Coastguard Worker 	/// The history index we are currently editing.
325*5a6e8488SAndroid Build Coastguard Worker 	size_t idx;
326*5a6e8488SAndroid Build Coastguard Worker 
327*5a6e8488SAndroid Build Coastguard Worker #ifndef _WIN32
328*5a6e8488SAndroid Build Coastguard Worker 	/// The original terminal state.
329*5a6e8488SAndroid Build Coastguard Worker 	struct termios orig_termios;
330*5a6e8488SAndroid Build Coastguard Worker #else // _WIN32
331*5a6e8488SAndroid Build Coastguard Worker 	///  The original input console mode.
332*5a6e8488SAndroid Build Coastguard Worker 	DWORD orig_in;
333*5a6e8488SAndroid Build Coastguard Worker 
334*5a6e8488SAndroid Build Coastguard Worker 	///  The original output console mode.
335*5a6e8488SAndroid Build Coastguard Worker 	DWORD orig_out;
336*5a6e8488SAndroid Build Coastguard Worker #endif // _WIN32
337*5a6e8488SAndroid Build Coastguard Worker 
338*5a6e8488SAndroid Build Coastguard Worker 	/// These next two are here because pahole found a 4 byte hole here.
339*5a6e8488SAndroid Build Coastguard Worker 
340*5a6e8488SAndroid Build Coastguard Worker 	/// Whether we are in rawmode.
341*5a6e8488SAndroid Build Coastguard Worker 	bool rawMode;
342*5a6e8488SAndroid Build Coastguard Worker 
343*5a6e8488SAndroid Build Coastguard Worker 	/// Whether the terminal is bad.
344*5a6e8488SAndroid Build Coastguard Worker 	bool badTerm;
345*5a6e8488SAndroid Build Coastguard Worker 
346*5a6e8488SAndroid Build Coastguard Worker #ifndef _WIN32
347*5a6e8488SAndroid Build Coastguard Worker 	/// This is to check if stdin has more data.
348*5a6e8488SAndroid Build Coastguard Worker 	fd_set rdset;
349*5a6e8488SAndroid Build Coastguard Worker 
350*5a6e8488SAndroid Build Coastguard Worker 	/// This is to check if stdin has more data.
351*5a6e8488SAndroid Build Coastguard Worker 	struct timespec ts;
352*5a6e8488SAndroid Build Coastguard Worker 
353*5a6e8488SAndroid Build Coastguard Worker 	/// This is to check if stdin has more data.
354*5a6e8488SAndroid Build Coastguard Worker 	sigset_t sigmask;
355*5a6e8488SAndroid Build Coastguard Worker #endif // _WIN32
356*5a6e8488SAndroid Build Coastguard Worker 
357*5a6e8488SAndroid Build Coastguard Worker } BcHistory;
358*5a6e8488SAndroid Build Coastguard Worker 
359*5a6e8488SAndroid Build Coastguard Worker /**
360*5a6e8488SAndroid Build Coastguard Worker  * Frees strings used by history.
361*5a6e8488SAndroid Build Coastguard Worker  * @param str  The string to free.
362*5a6e8488SAndroid Build Coastguard Worker  */
363*5a6e8488SAndroid Build Coastguard Worker void
364*5a6e8488SAndroid Build Coastguard Worker bc_history_string_free(void* str);
365*5a6e8488SAndroid Build Coastguard Worker 
366*5a6e8488SAndroid Build Coastguard Worker // A list of terminals that don't work.
367*5a6e8488SAndroid Build Coastguard Worker extern const char* bc_history_bad_terms[];
368*5a6e8488SAndroid Build Coastguard Worker 
369*5a6e8488SAndroid Build Coastguard Worker // A tab in history and its length.
370*5a6e8488SAndroid Build Coastguard Worker extern const char bc_history_tab[];
371*5a6e8488SAndroid Build Coastguard Worker extern const size_t bc_history_tab_len;
372*5a6e8488SAndroid Build Coastguard Worker 
373*5a6e8488SAndroid Build Coastguard Worker // A ctrl+c string.
374*5a6e8488SAndroid Build Coastguard Worker extern const char bc_history_ctrlc[];
375*5a6e8488SAndroid Build Coastguard Worker 
376*5a6e8488SAndroid Build Coastguard Worker // UTF-8 data arrays.
377*5a6e8488SAndroid Build Coastguard Worker extern const uint32_t bc_history_wchars[][2];
378*5a6e8488SAndroid Build Coastguard Worker extern const size_t bc_history_wchars_len;
379*5a6e8488SAndroid Build Coastguard Worker extern const uint32_t bc_history_combo_chars[];
380*5a6e8488SAndroid Build Coastguard Worker extern const size_t bc_history_combo_chars_len;
381*5a6e8488SAndroid Build Coastguard Worker 
382*5a6e8488SAndroid Build Coastguard Worker #if BC_DEBUG_CODE
383*5a6e8488SAndroid Build Coastguard Worker 
384*5a6e8488SAndroid Build Coastguard Worker // Debug data.
385*5a6e8488SAndroid Build Coastguard Worker extern BcFile bc_history_debug_fp;
386*5a6e8488SAndroid Build Coastguard Worker extern char* bc_history_debug_buf;
387*5a6e8488SAndroid Build Coastguard Worker 
388*5a6e8488SAndroid Build Coastguard Worker /**
389*5a6e8488SAndroid Build Coastguard Worker  * A function to print keycodes for debugging.
390*5a6e8488SAndroid Build Coastguard Worker  * @param h  The history data.
391*5a6e8488SAndroid Build Coastguard Worker  */
392*5a6e8488SAndroid Build Coastguard Worker void
393*5a6e8488SAndroid Build Coastguard Worker bc_history_printKeyCodes(BcHistory* h);
394*5a6e8488SAndroid Build Coastguard Worker 
395*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEBUG_CODE
396*5a6e8488SAndroid Build Coastguard Worker 
397*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_HISTORY
398*5a6e8488SAndroid Build Coastguard Worker 
399*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_READLINE
400*5a6e8488SAndroid Build Coastguard Worker 
401*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EDITLINE
402*5a6e8488SAndroid Build Coastguard Worker 
403*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_HISTORY
404*5a6e8488SAndroid Build Coastguard Worker 
405*5a6e8488SAndroid Build Coastguard Worker /**
406*5a6e8488SAndroid Build Coastguard Worker  * Get a line from stdin using history. This returns a status because I don't
407*5a6e8488SAndroid Build Coastguard Worker  * want to throw errors while the terminal is in raw mode.
408*5a6e8488SAndroid Build Coastguard Worker  * @param h       The history data.
409*5a6e8488SAndroid Build Coastguard Worker  * @param vec     A vector to put the line into.
410*5a6e8488SAndroid Build Coastguard Worker  * @param prompt  The prompt to display, if desired.
411*5a6e8488SAndroid Build Coastguard Worker  * @return        A status indicating an error, if any. Returning a status here
412*5a6e8488SAndroid Build Coastguard Worker  *                is better because if we throw an error out of history, we
413*5a6e8488SAndroid Build Coastguard Worker  *                leave the terminal in raw mode or in some other half-baked
414*5a6e8488SAndroid Build Coastguard Worker  *                state.
415*5a6e8488SAndroid Build Coastguard Worker  */
416*5a6e8488SAndroid Build Coastguard Worker BcStatus
417*5a6e8488SAndroid Build Coastguard Worker bc_history_line(BcHistory* h, BcVec* vec, const char* prompt);
418*5a6e8488SAndroid Build Coastguard Worker 
419*5a6e8488SAndroid Build Coastguard Worker /**
420*5a6e8488SAndroid Build Coastguard Worker  * Initialize history data.
421*5a6e8488SAndroid Build Coastguard Worker  * @param h  The struct to initialize.
422*5a6e8488SAndroid Build Coastguard Worker  */
423*5a6e8488SAndroid Build Coastguard Worker void
424*5a6e8488SAndroid Build Coastguard Worker bc_history_init(BcHistory* h);
425*5a6e8488SAndroid Build Coastguard Worker 
426*5a6e8488SAndroid Build Coastguard Worker /**
427*5a6e8488SAndroid Build Coastguard Worker  * Free history data (and recook the terminal).
428*5a6e8488SAndroid Build Coastguard Worker  * @param h  The struct to free.
429*5a6e8488SAndroid Build Coastguard Worker  */
430*5a6e8488SAndroid Build Coastguard Worker void
431*5a6e8488SAndroid Build Coastguard Worker bc_history_free(BcHistory* h);
432*5a6e8488SAndroid Build Coastguard Worker 
433*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_HISTORY
434*5a6e8488SAndroid Build Coastguard Worker 
435*5a6e8488SAndroid Build Coastguard Worker #endif // BC_HISTORY_H
436