Indirect calls are more difficult to predict.
Unfortunately, on x64 direct call is 5 bytes while indirect "call (reg+ofs)"
is 3 bytes:
function old new delta
i_getch - 82 +82
i_peek - 63 +63
parse_stream 2531 2579 +48
parse_dollar 771 797 +26
parse_redirect 296 321 +25
add_till_closing_bracket 408 420 +12
encode_string 256 265 +9
i_peek_and_eat_bkslash_nl 93 99 +6
add_till_backquote 110 114 +4
parse_and_run_stream 139 141 +2
expand_vars_to_list 1143 1144 +1
static_peek 6 - -6
setup_string_in_str 39 18 -21
setup_file_in_str 40 19 -21
static_get 27 - -27
file_peek 52 - -52
file_get 65 - -65
------------------------------------------------------------------------------
(add/remove: 2/4 grow/shrink: 9/2 up/down: 278/-192) Total: 86 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
int peek_buf[2];
int last_char;
FILE *file;
int peek_buf[2];
int last_char;
FILE *file;
- int (*get) (struct in_str *) FAST_FUNC;
- int (*peek) (struct in_str *) FAST_FUNC;
-#define i_getch(input) ((input)->get(input))
-#define i_peek(input) ((input)->peek(input))
/* The descrip member of this structure is only used to make
* debugging output pretty */
/* The descrip member of this structure is only used to make
* debugging output pretty */
}
#endif /* INTERACTIVE */
}
#endif /* INTERACTIVE */
-static int FAST_FUNC file_get(struct in_str *i)
+static int i_getch(struct in_str *i)
+ if (!i->file) {
+ /* string-based in_str */
+ ch = (unsigned char)*i->p;
+ if (ch != '\0') {
+ i->p++;
+ i->last_char = ch;
+ return ch;
+ }
+ return EOF;
+ }
+
+ /* FILE-based in_str */
+
#if ENABLE_FEATURE_EDITING
/* This can be stdin, check line editing char[] buffer */
if (i->p && *i->p != '\0') {
#if ENABLE_FEATURE_EDITING
/* This can be stdin, check line editing char[] buffer */
if (i->p && *i->p != '\0') {
-static int FAST_FUNC file_peek(struct in_str *i)
+static int i_peek(struct in_str *i)
+ if (!i->file) {
+ /* string-based in_str */
+ /* Doesn't report EOF on NUL. None of the callers care. */
+ return (unsigned char)*i->p;
+ }
+
+ /* FILE-based in_str */
+
#if ENABLE_FEATURE_EDITING && ENABLE_HUSH_INTERACTIVE
/* This can be stdin, check line editing char[] buffer */
if (i->p && *i->p != '\0')
#if ENABLE_FEATURE_EDITING && ENABLE_HUSH_INTERACTIVE
/* This can be stdin, check line editing char[] buffer */
if (i->p && *i->p != '\0')
-static int FAST_FUNC static_get(struct in_str *i)
-{
- int ch = (unsigned char)*i->p;
- if (ch != '\0') {
- i->p++;
- i->last_char = ch;
- return ch;
- }
- return EOF;
-}
-
-static int FAST_FUNC static_peek(struct in_str *i)
-{
- /* Doesn't report EOF on NUL. None of the callers care. */
- return (unsigned char)*i->p;
-}
-
/* Only ever called if i_peek() was called, and did not return EOF.
* IOW: we know the previous peek saw an ordinary char, not EOF, not NUL,
* not end-of-line. Therefore we never need to read a new editing line here.
/* Only ever called if i_peek() was called, and did not return EOF.
* IOW: we know the previous peek saw an ordinary char, not EOF, not NUL,
* not end-of-line. Therefore we never need to read a new editing line here.
static void setup_file_in_str(struct in_str *i, FILE *f)
{
memset(i, 0, sizeof(*i));
static void setup_file_in_str(struct in_str *i, FILE *f)
{
memset(i, 0, sizeof(*i));
- i->get = file_get;
- i->peek = file_peek;
/* i->promptmode = 0; - PS1 (memset did it) */
i->file = f;
/* i->p = NULL; */
/* i->promptmode = 0; - PS1 (memset did it) */
i->file = f;
/* i->p = NULL; */
static void setup_string_in_str(struct in_str *i, const char *s)
{
memset(i, 0, sizeof(*i));
static void setup_string_in_str(struct in_str *i, const char *s)
{
memset(i, 0, sizeof(*i));
- i->get = static_get;
- i->peek = static_peek;
/* i->promptmode = 0; - PS1 (memset did it) */
/* i->promptmode = 0; - PS1 (memset did it) */