From ca46040007b6d5208681fa7f16567ced14814807 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sat, 14 Jun 2014 19:22:41 +0000 Subject: [PATCH] Enabled use of libedit as alternative to libreadline --- acinclude.m4 | 53 +++++++- configure.ac | 16 +++ xorriso/base_obj.c | 8 +- xorriso/configure_ac.txt | 20 +++ xorriso/lib_mgt.c | 6 +- xorriso/opts_d_h.c | 10 +- xorriso/text_io.c | 264 +++++++++++++++++++++++++++++++----- xorriso/xorriso_timestamp.h | 2 +- 8 files changed, 340 insertions(+), 39 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 299dbdcb..f799c049 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -144,6 +144,56 @@ iconv_close(cd); ]) +dnl LIBBURNIA_TRY_EDITLINE is by Thomas Schmitt, libburnia project +dnl It performs the actual test compilation for editline. +dnl Variable LIBS has to be set by the caller. +AC_DEFUN([LIBBURNIA_TRY_EDITLINE], +[ + AC_TRY_LINK([ +#include +#include +#include +#include +#include +#include +#include ], +[EditLine *editline_handle; History *editline_history; HistEvent ev; int count; +editline_handle= el_init("dummy", stdin, stdout, stderr); +el_set(editline_handle, EL_EDITOR, "emacs"); +editline_history= history_init(); +history(editline_history, &ev, H_SETSIZE, 1000); +el_gets(editline_handle, &count); +], [editline_test="yes"], [editline_test="no"] + ) +]) + +dnl LIBBURNIA_ASSERT_EDITLINE is by Thomas Schmitt, libburnia project +dnl It disables xorriso editline if not all needed functions are present +AC_DEFUN([LIBBURNIA_ASSERT_EDITLINE], +[ + if test x$XORRISO_ASSUME_EDITLINE = x + then + dnl Check for the essential gestures of xorriso/text_io.c + AC_MSG_CHECKING([for desired functions in libedit]) + libburnia_save_LIBS="$LIBS" + LIBS="$LIBS -ledit" + LIBBURNIA_TRY_EDITLINE + if test x$editline_test = xno + then + LIBS="$libburnia_save_LIBS" + LIBS="$LIBS -ledit" + LIBBURNIA_TRY_EDITLINE + fi + if test x$editline_test = xno + then + READLINE_DEF= + LIBS="$libburnia_save_LIBS" + fi + AC_MSG_RESULT([$editline_test $editline_msg]) + fi +]) + + dnl LIBBURNIA_TRY_READLINE is by Thomas Schmitt, libburnia project dnl It performs the actual test compilation for readline. dnl Variable LIBS has to be set by the caller. @@ -166,14 +216,13 @@ hl= history_list(); ) ]) - dnl LIBBURNIA_ASSERT_READLINE is by Thomas Schmitt, libburnia project dnl It disables xorriso readline if not all needed functions are present AC_DEFUN([LIBBURNIA_ASSERT_READLINE], [ if test x$XORRISO_ASSUME_READLINE = x then - dnl Check for the essential gestures of libisofs/util.c + dnl Check for the essential gestures of xorriso/text_io.c AC_MSG_CHECKING([for desired functions in libreadline]) readline_msg= libburnia_save_LIBS="$LIBS" diff --git a/configure.ac b/configure.ac index e72d90da..229ed7f0 100644 --- a/configure.ac +++ b/configure.ac @@ -144,8 +144,24 @@ dnl The X= in the yes case prevents that -lreadline gets linked twice else READLINE_DEF= fi +if test x$READLINE_DEF = x; then + AC_ARG_ENABLE(libedit, + [ --enable-libedit Enable use of libedit by xorriso if not libreadline, default=yes], + , enable_libedit=yes) + if test x$enable_libedit = xyes; then +dnl Check whether there is development and runtime support. +dnl If not, erase this macro which would enable use of el_*(), history*() + READLINE_DEF="-DXorriso_with_editlinE" + + LIBBURNIA_ASSERT_EDITLINE + + else + READLINE_DEF= + fi +fi AC_SUBST(READLINE_DEF) + dnl ts A90329 dnl ACL and xattr do not need to be enabled in libisoburn or xorriso source dnl but without AC_CHECK_LIB() xorriso will not be linked with -lacl . diff --git a/xorriso/base_obj.c b/xorriso/base_obj.c index 43327e63..5832036b 100644 --- a/xorriso/base_obj.c +++ b/xorriso/base_obj.c @@ -3,7 +3,7 @@ /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. - Copyright 2007-2013 Thomas Schmitt, + Copyright 2007-2014 Thomas Schmitt, Provided under GPL version 2 or later. @@ -111,6 +111,9 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) free(leafname); return(-1); } + + /* Base initialization by actions which must not fail */ + m->libs_are_started= 0; strncpy(m->progname,progname,sizeof(m->progname)-1); m->progname[sizeof(m->progname)-1]= 0; @@ -431,6 +434,9 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) m->info_text[0]= 0; + + /* Here begin actions which might fail */ + ret= Sfile_leafname(progname, leafname, 0); if(ret<=0) goto failure; diff --git a/xorriso/configure_ac.txt b/xorriso/configure_ac.txt index fc261bf6..5730b373 100644 --- a/xorriso/configure_ac.txt +++ b/xorriso/configure_ac.txt @@ -174,9 +174,29 @@ dnl The X= in the yes case prevents that -lreadline gets linked twice else READLINE_DEF= fi +if test x$READLINE_DEF = x; then + AH_TEMPLATE([Xorriso_with_editlinE], + [Define to use libedit if not libreadline]) + AC_ARG_ENABLE(libedit, + [ --enable-libedit Enable use of libedit by xorriso if not libreadline, default=yes], + , enable_libedit=yes) + if test x$enable_libedit = xyes; then +dnl Check whether there is development and runtime support. +dnl If not, erase this macro which would enable use of el_*(), history*() + READLINE_DEF="-DXorriso_with_editlinE" + + LIBBURNIA_ASSERT_EDITLINE + + else + READLINE_DEF= + fi +fi if test x$READLINE_DEF = x-DXorriso_with_readlinE then AC_DEFINE([Xorriso_with_readlinE], []) +elif test x$READLINE_DEF = x-DXorriso_with_editlinE +then + AC_DEFINE([Xorriso_with_editlinE], []) fi AH_TEMPLATE([Libisofs_with_aaip_acL], [Define to use ACL capabilities]) diff --git a/xorriso/lib_mgt.c b/xorriso/lib_mgt.c index 27271838..d6214573 100644 --- a/xorriso/lib_mgt.c +++ b/xorriso/lib_mgt.c @@ -1,7 +1,7 @@ /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. - Copyright 2007-2011 Thomas Schmitt, + Copyright 2007-2014 Thomas Schmitt, Provided under GPL version 2 or later. @@ -929,10 +929,14 @@ int Xorriso_list_extras(struct XorrisO *xorriso, char *mode, int flag) Xorriso_list_extras_result(xorriso, mode, "dvd_obs", 0); sprintf(xorriso->result_line, "Readline : %s\n", +#ifdef Xorriso_with_editlinE + "yes , libedit"); +#else #ifdef Xorriso_with_readlinE "yes"); #else "no"); +#endif #endif Xorriso_list_extras_result(xorriso, mode, "use_readline", 0); diff --git a/xorriso/opts_d_h.c b/xorriso/opts_d_h.c index f7e04e67..36518e2e 100644 --- a/xorriso/opts_d_h.c +++ b/xorriso/opts_d_h.c @@ -29,6 +29,12 @@ #include "xorriso_private.h" #include "xorrisoburn.h" +#ifdef Xorriso_with_readlinE +#define Xorriso_with_line_editoR +#endif +#ifdef Xorriso_with_editlinE +#define Xorriso_with_line_editoR +#endif /* Command -data_cache_size */ int Xorriso_option_data_cache_size(struct XorrisO *xorriso, char *num_tiles, @@ -2185,12 +2191,12 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " -page len width Prompt user after len output lines (0=no prompt).", " width (default 80) can adjust line number computation", " to the output terminal's line width.", -#ifdef Xorriso_with_readlinE +#ifdef Xorriso_with_line_editoR " -use_readline \"on\"|\"off\"", " Whether to use libreadline for dialog if available.", " -history text Copy text into libreadline history. This command", " itself is not copied to the history list.", -#endif /* Xorriso_with_readlinE */ +#endif /* Xorriso_with_line_editoR */ " -sh_style_result \"on\"|\"off\"", " If \"on\" do not wrap file addresses in quotation marks with", " -pwd -pwdx -ls -lsd -lsl -lsdl -lsx -lsdx -lslx -lsdlx", diff --git a/xorriso/text_io.c b/xorriso/text_io.c index 431b52df..41866ae5 100644 --- a/xorriso/text_io.c +++ b/xorriso/text_io.c @@ -41,8 +41,14 @@ #include #include #endif /* ! Xorriso_with_old_readlinE */ +#define Xorriso_with_line_editoR yes #endif /* Xorriso_with_readlinE */ +#ifdef Xorriso_with_editlinE +#include +#define Xorriso_with_line_editoR yes +#endif /* Xorriso_with_editlinE */ + #include "xorriso.h" #include "xorriso_private.h" @@ -59,6 +65,218 @@ int Xorriso_protect_stdout(struct XorrisO *xorriso, int flag) return(1); } +#ifdef Xorriso_with_editlinE + +/* These have to be global and shared by all XorrisOs which might be active. +*/ +static EditLine *editline_handle= NULL; +static History *editline_history= NULL; +static int editline_is_initialized= 0; + +char *Xorriso__editline_prompt(EditLine *el_handle) +{ + return ""; +} + + +void Xorriso_init_editline(struct XorrisO *xorriso, int flag) +{ + HistEvent ev; + + /* >>> Need mutex */ + + if(editline_is_initialized != 0) + return; + editline_is_initialized= -1; /* Invalid */ + + editline_handle= el_init(xorriso->progname, stdin, stdout, stderr); + if(editline_handle == NULL) + return; + el_set(editline_handle, EL_EDITOR, "emacs"); + el_set(editline_handle, EL_PROMPT, &Xorriso__editline_prompt); + + editline_history= history_init(); + if(editline_history == NULL) + return; + history(editline_history, &ev, H_SETSIZE, 1000); + el_set(editline_handle, EL_HIST, history, editline_history); + + /* >>> ??? where to apply history_end() and el_end() ? */; + + editline_is_initialized= 1; /* Valid now */ + return; +} + +#endif /* Xorriso_with_editlinE */ + +#ifdef Xorriso_with_line_editoR + +char *Xorriso_emul_readline(struct XorrisO *xorriso, int flag) +{ + +#ifdef Xorriso_with_editlinE + + const char *cpt; + int count= 0; + char *retpt; + + /* >>> Need mutex */ + + Xorriso_init_editline(xorriso, 0); + if(editline_is_initialized < 0) { + + /* >>> fallback */; + + } + + cpt= el_gets(editline_handle, &count); + if(count == -1 || cpt == NULL) + return(NULL); + retpt= calloc(1, count + 1); + if(retpt == NULL) + return(NULL); + memcpy(retpt, cpt, count); + retpt[count]= 0; + return(retpt); + +#else + +#ifdef Xorriso_with_readlinE + + char *cpt; + + cpt= readline(""); + return(cpt); + +#else + + return(NULL); + +#endif /* ! Xorriso_with_readlinE */ +#endif /* ! Xorriso_with_editlinE */ +} + + +void Xorriso_emul_add_history(struct XorrisO *xorriso, char *line, int flag) +{ +#ifdef Xorriso_with_editlinE + + HistEvent ev; + + /* >>> Need mutex */ + + Xorriso_init_editline(xorriso, 0); + if(editline_is_initialized < 0) + return; + + history(editline_history, &ev, H_ENTER, line); + +#else + +#ifdef Xorriso_with_readlinE + + add_history(line); + +#else + + /* ??? How to raise protest ? */; + +#endif /* ! Xorriso_with_readlinE */ +#endif /* ! Xorriso_with_editlinE */ +} + + +/* @param flag bit1= do only report to fp +*/ +int Xorriso_status_history(struct XorrisO *xorriso, char *filter, FILE *fp, + int flag) +{ + +#ifdef Xorriso_with_editlinE + + int ret, l; + HistEvent ev; + int hc, i, was_end= 0; + char *str= NULL; + + + /* >>> Need mutex */ + + Xorriso_init_editline(xorriso, 0); + if(editline_is_initialized < 0) + {ret= 0; goto ex;} + + Xorriso_alloc_meM(str, char, SfileadrL); + + ret= history(editline_history, &ev, H_LAST); + for(hc= 0; ret != -1; hc++) { + ret= history(editline_history, &ev, H_PREV); + was_end = (strcmp(ev.str, "-end") == 0); + } + if(was_end) + hc--; + if(hc >= xorriso->status_history_max) + i= hc - xorriso->status_history_max; + else + i= 0; + + ret= history(editline_history, &ev, H_LAST); + for(; i < hc && ret != -1; i++) { + /* Eat newline at line end */ + strncpy(str, ev.str, SfileadrL - 1); + str[SfileadrL - 1]= 0; + l= strlen(str); + if(l > 0) + if(str[l - 1] == '\n') + str[l - 1]= 0; + + sprintf(xorriso->result_line, "-history "); + Text_shellsafe(str, xorriso->result_line, 1); + strcat(xorriso->result_line, "\n"); + Xorriso_status_result(xorriso, filter, fp, flag & 2); + ret= history(editline_history, &ev, H_PREV); + } + ret= 1; +ex:; + Xorriso_free_meM(str); + return(ret); + +#else +#ifdef Xorriso_with_readlinE + + HIST_ENTRY **hl; + int hc, i; + + hl= history_list(); + if(hl != NULL) { + for(hc= 0; hl[hc] != NULL; hc++); + if(hc > 0) + if(strcmp(hl[hc-1]->line, "-end") == 0) + hc--; + if(hc >= xorriso->status_history_max) + i= hc - xorriso->status_history_max; + else + i= 0; + for(; i < hc; i++) { + sprintf(xorriso->result_line, "-history "); + Text_shellsafe(hl[i]->line, xorriso->result_line, 1); + strcat(xorriso->result_line, "\n"); + Xorriso_status_result(xorriso, filter, fp, flag & 2); + } + } + return(1); + +#else /* Xorriso_with_readlinE */ + + return(0); + +#endif /* ! Xorriso_with_readlinE */ +#endif /* ! Xorriso_with_editlinE */ + +} + +#endif /* Xorriso_with_line_editoR */ + int Xorriso_dialog_input(struct XorrisO *xorriso, char line[], int linesize, int flag) @@ -73,10 +291,10 @@ int Xorriso_dialog_input(struct XorrisO *xorriso, char line[], int linesize, { char *cpt= NULL, **argv= NULL, *linept, *why_append= ""; int ret, argc= 0, base_length= 0, l, append_line; -#ifdef Xorriso_with_readlinE +#ifdef Xorriso_with_line_editoR static char last_input[SfileadrL]= {""}; int no_history= 0; -#endif /* ! Xorriso_with_readlinE */ +#endif /* Xorriso_with_line_editoR */ double tdiff; struct timeval tv; struct timezone tz; @@ -88,7 +306,7 @@ int Xorriso_dialog_input(struct XorrisO *xorriso, char line[], int linesize, fflush(stdout); linept= line; -#ifdef Xorriso_with_readlinE +#ifdef Xorriso_with_line_editoR no_history= (flag & 1) || xorriso->use_stdin; #endif @@ -103,7 +321,7 @@ get_single:; goto process_single; } -#ifdef Xorriso_with_readlinE +#ifdef Xorriso_with_line_editoR if(xorriso->use_stdin || xorriso->dev_fd_1>=0 || xorriso->tolerate_stdin_eof) { @@ -125,7 +343,7 @@ get_single:; if(flag&2) { cpt= NULL; } else { - cpt= readline(""); + cpt= Xorriso_emul_readline(xorriso, 0); if(cpt==NULL) { /* need a very dramatic end */ kill(getpid(),SIGHUP); @@ -142,7 +360,7 @@ get_single:; strcpy(linept, cpt); } -#else /* Xorriso_with_readlinE */ +#else /* Xorriso_with_line_editoR */ if(flag&2) {ret= 1; goto ex;} @@ -155,7 +373,7 @@ get_single:; {ret= -1; goto ex;} } -#endif /* ! Xorriso_with_readlinE */ +#endif /* ! Xorriso_with_line_editoR */ process_single:; @@ -209,19 +427,19 @@ new_empty:; } } -#ifdef Xorriso_with_readlinE +#ifdef Xorriso_with_line_editoR put_into_history:; if((flag & 32) || (line[0]!=0 && strcmp(last_input,line)!=0 && !no_history)) { if(!((flag&4) && (strncmp(line,"-history:",9)==0 || strncmp(line,"-history ",9)==0))) { - add_history(line); + Xorriso_emul_add_history(xorriso, line, 0); strncpy(last_input,line,sizeof(last_input)-1); last_input[sizeof(last_input)-1]= 0; } } -#endif /* ! Xorriso_with_readlinE */ +#endif /* Xorriso_with_line_editoR */ ret= 1; ex:; @@ -3185,30 +3403,12 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag) Xorriso_status_result(xorriso,filter,fp,flag&2); } -#ifdef Xorriso_with_readlinE +#ifdef Xorriso_with_line_editoR - if((flag&8) && xorriso->status_history_max>0) { - HIST_ENTRY **hl; - int hc,i; + if((flag & 8) && xorriso->status_history_max > 0 && !xorriso->use_stdin) + Xorriso_status_history(xorriso, filter, fp, flag & 2); - hl= history_list(); - if(hl!=NULL) { - for(hc= 0;hl[hc]!=NULL;hc++); - if(hc>0) - if(strcmp(hl[hc-1]->line,"-end")==0) - hc--; - if(hc>=xorriso->status_history_max) - i= hc-xorriso->status_history_max; - else - i= 0; - for(;iline,sfe,0)); - Xorriso_status_result(xorriso,filter,fp,flag&2); - } - } - } - -#endif /* Xorriso_with_readlinE */ +#endif /* Xorriso_with_line_editoR */ is_default= (xorriso->toc_emulation_flag == 0); sprintf(line,"-rom_toc_scan %s:%s:%s\n", diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index e77c8cad..9dfbd048 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2014.06.14.185146" +#define Xorriso_timestamP "2014.06.14.192149"