-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathesh_internal.h
178 lines (156 loc) · 4.85 KB
/
esh_internal.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
* esh - embedded shell
* Copyright (C) 2017 Chris Pavlina
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef ESH_INTERNAL_INCLUDE
#error "esh_internal.h is an internal file and should not be included directly"
#endif // ESH_INTERNAL_INCLUDE
#ifndef ESH_INTERNAL_H
#define ESH_INTERNAL_H
#include <esh_incl_config.h>
#include <esh_hist.h>
/**
* If we're building for Rust, we need to know the size of a &[u8] in order
* to allocate space for it. This definition should be equivalent. Because the
* internal representation of a slice has not been stabilized [1], this is not
* guaranteed to remain constant in the future; the Rust bindings will check
* sizeof(struct char_slice) against mem::size_of::<&[u8]>().
*
* [1] https://github.com/rust-lang/rust/issues/27751
*/
#ifdef ESH_RUST
struct char_slice {
char *p;
size_t sz;
};
#endif
/**
* esh instance struct. This holds all of the state that needs to be saved
* between calls to esh_rx().
*/
typedef struct esh {
/**
* The config item ESH_BUFFER_LEN is only the number of characters to be
* stored, not characters plus termination.
*/
char buffer[ESH_BUFFER_LEN + 1];
/**
* The Rust bindings require space allocated for an argv array of &[u8],
* which can share memory with C's char* array to save limited SRAM.
*/
#ifdef ESH_RUST
union {
char * argv[ESH_ARGC_MAX];
struct char_slice rust_argv[ESH_ARGC_MAX];
};
#else
char * argv[ESH_ARGC_MAX];
#endif
size_t cnt; ///< Number of characters currently held in .buffer
size_t ins; ///< Position of the current insertion point
uint8_t flags; ///< State flags for escape sequence parser
struct esh_hist hist;
#ifndef ESH_STATIC_CALLBACKS
esh_cb_command cb_command;
esh_cb_print print;
esh_cb_overflow overflow;
#endif
void *cb_command_arg;
void *cb_print_arg;
void *cb_overflow_arg;
} esh_t;
/**
* On AVR, a number of strings should be stored in and read from flash space.
* Other architectures have linearized address spaces and don't require this.
*/
#ifdef __AVR_ARCH__
# define FSTR(s) (__extension__({ \
static const __flash char __c[] = (s); \
&__c[0];}))
# define AVR_ONLY(x) x
#else
# define FSTR(s) (s)
# define AVR_ONLY(x)
#endif // __AVR_ARCH__
/**
* Print one character.
* @return false (allows it to be an esh_hist_for_each_char callback)
*/
bool esh_putc(esh_t * esh, char c);
/**
* @internal
* Print a string located in RAM.
*/
bool esh_puts(esh_t * esh, char const * s);
/**
* @internal
* Print a string located in flash. On all but AVR this is an alias for
* esh_puts().
*/
#ifdef __AVR_ARCH__
bool esh_puts_flash(esh_t * esh, char const __flash * s);
#else
#define esh_puts_flash esh_puts
#endif
/**
* Print the prompt string
*/
void esh_print_prompt(esh_t * esh);
/**
* Overwrite the prompt and restore the buffer.
*/
void esh_restore(esh_t * esh);
/**
* Call the print callback. Wrapper to avoid ifdefs for static callback.
*/
void esh_do_print_callback(esh_t * esh, char c);
/**
* Call the main callback. Wrapper to avoid ifdefs for static callback.
*/
void esh_do_callback(esh_t * esh, int argc, char ** argv);
/**
* Call the overflow callback. Wrapper to avoid ifdefs for the static
* callback.
*/
void esh_do_overflow_callback(esh_t * esh, char const * buffer);
#ifdef ESH_RUST
/**
* Return what we think the size of a Rust &[u8] slice is. This is used to
* verify that the statically allocated slice array is long enough, and also
* to make sure a linker error is produced if ESH_RUST wasn't enabled
* (which would mean the slice array wasn't allocated at all).
*/
size_t esh_get_slice_size(void);
#endif
#define ESC_CURSOR_RIGHT "\33[1C"
#define ESC_CURSOR_LEFT "\33[1D"
#define ESC_ERASE_LINE "\33[2K"
#define ESCCHAR_UP 'A'
#define ESCCHAR_DOWN 'B'
#define ESCCHAR_RIGHT 'C'
#define ESCCHAR_LEFT 'D'
#define ESCCHAR_HOME 'H'
#define ESCCHAR_END 'F'
#define ESCCHAR_CTRLLEFT 'd'
#define ESCCHAR_CTRLRIGHT 'c'
#if ESH_ALLOC == STATIC
extern esh_t g_esh_struct;
#define ESH_INSTANCE (&g_esh_struct)
#else
#define ESH_INSTANCE esh
#endif // ESH_ALLOC
#endif // ESH_INTERNAL_H