readline input is fed into Lex.
This adds commands history.
There is also a configure option to disable readline support.
AC_PROG_RANLIB
AM_PROG_AR
+AC_ARG_WITH([readline],
+ [AS_HELP_STRING([--without-readline], [disable support for readline])],
+ [],
+ [with_readline=yes])
+
+LIBREADLINE=
+ AS_IF([test "x$with_readline" != xno],
+ [AC_CHECK_LIB([readline], [main],
+ [AC_SUBST([LIBREADLINE], ["-lreadline"])
+ AC_DEFINE([HAVE_LIBREADLINE], [1],
+ [Define if you have libreadline])
+ ],
+ [AC_MSG_FAILURE(
+ [readline test failed (--without-readline to disable)])],
+ []
+)])
+
dnl Testing for Lex/Yacc
AC_PROG_LEX
AC_PROG_YACC
-I@top_srcdir@ \
-I@top_srcdir@/src/common
+# Option -d: produce header file scanner.h
+AM_LFLAGS = --header-file=scanner.h
+
# Option -d: produce header file parser.h
AM_YFLAGS = -d
LDADD = \
+ $(LIBREADLINE) \
$(top_builddir)/src/common/libemu8051.a
bin_PROGRAMS = emu8051-cli
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include "config.h"
+
#include <stdbool.h>
#include <stdio.h>
-#include "config.h"
#include "common.h"
#include "cpu8051.h"
#include "options.h"
} else {
menu_display_usage();
console_show_registers();
- menu_prompt();
yyparse();
}
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include "config.h"
+
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
+#ifdef HAVE_LIBREADLINE
+#include <readline/readline.h>
+#include <readline/history.h>
+#endif /* HAVE_LIBREADLINE */
#include "common.h"
#include "cpu8051.h"
#include "options.h"
#include "hexfile.h"
#include "keyboard.h"
+#include "scanner.h"
#include "menu.h"
extern struct options_t options;
-void
-menu_prompt(void)
+#define YY_NULL 0
+
+#define MENU_PROMPT "-> "
+
+int
+menu_get_input(char *buf, ssize_t size)
{
- printf("-> ");
+ char *line;
+ int max_len;
+
+ max_len = size - 2;
+
+ if (feof(yyin))
+ return YY_NULL;
+
+#ifdef HAVE_LIBREADLINE
+ /* Get the input line, and if non-empty, place it in the history. */
+ line = readline(MENU_PROMPT);
+ if (!line)
+ return YY_NULL;
+
+ if (line && *line)
+ add_history(line);
+
+ if ((int) strlen(line) > max_len) {
+ printf("input line too long");
+ return YY_NULL;
+ }
+
+ strcpy(buf, line);
+
+ /* Readline never gives you the last '\n', so add it back for Lex. */
+ strcat(buf, "\n");
+
+ free(line);
+#else
+ /* It's okay to print a prompt if we are redirecting stdout,
+ * as long as stdin is still a tty. Otherwise, don't print
+ * a prompt at all if stdin is redirected.
+ */
+ (void) fputs(MENU_PROMPT, stdout);
+ (void) fflush(stdout); /* for svr4 */
+ line = fgets(buf, max_len, stdin);
+ if (!line)
+ return YY_NULL;
+#endif
+
+ return strlen(buf);
}
void
int
yyparse(void);
-void
-menu_prompt(void);
+int
+menu_get_input(char *buf, ssize_t size);
void
menu_display_usage(void);
%%
-start : start command { menu_prompt(); }
+start : start command
| error TOK_ENTER {
/* In case of error, discard entire line */
yyerrok;
- menu_prompt();
}
- | start TOK_ENTER { menu_prompt(); }
+ | start TOK_ENTER
|
;
%option noinput
%option nounput
%{
+ #include "menu.h"
#include "parser.h"
#include "hexfile.h"
+
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result = menu_get_input(buf, max_size);
+
%}
digit [0-9]