diff --git a/CMakeLists.txt b/CMakeLists.txt index bd52180..351b860 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,6 +108,54 @@ else ( MSVC ) endif ( MSVC ) # End configure secp256k1-zkp +# Configure editline +if ( MSVC ) + # autoconf won't work here, hard code the defines + set( EDITLINE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline" ) + + file( GLOB EDITLINE_SOURCES "${EDITLINE_DIR}/src/editline.c" ) + add_library( editline ${EDITLINE_SOURCES} ) + + target_include_directories( editline PRIVATE "${EDITLINE_DIR}" PUBLIC "${EDITLINE_DIR}/include" ) + + set_target_properties( editline PROPERTIES COMPILE_DEFINITIONS LINKER_LANGUAGE C ) +else ( MSVC ) + include(ExternalProject) + if ( MINGW ) + ExternalProject_Add( project_editline + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/vendor/editline + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/vendor/editline --host=x86_64-w64-mingw32 + BUILD_COMMAND make + INSTALL_COMMAND true + BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/vendor/editline/src/project_editline-build/.libs/libeditline.a + ) + else ( MINGW ) + ExternalProject_Add( project_editline + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/vendor/editline + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/vendor/editline + BUILD_COMMAND make + INSTALL_COMMAND true + BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/vendor/editline/src/project_editline-build/.libs/libeditline.a + ) + endif ( MINGW ) + ExternalProject_Add_Step(project_editline autogen + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline/autogen.sh + DEPENDERS configure + ) + + ExternalProject_Get_Property(project_editline binary_dir) + + add_library(editline STATIC IMPORTED) + set_property(TARGET editline PROPERTY IMPORTED_LOCATION ${binary_dir}/src/.libs/libeditline${CMAKE_STATIC_LIBRARY_SUFFIX}) + set_property(TARGET editline PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline/include) + add_dependencies(editline project_editline) + install( FILES ${binary_dir}/src/.libs/libeditline${CMAKE_STATIC_LIBRARY_SUFFIX} DESTINATION lib/cryptonomex ) +endif ( MSVC ) +# End configure editline + IF( WIN32 ) MESSAGE(STATUS "Configuring fc to build on Win32") @@ -258,27 +306,17 @@ add_subdirectory( vendor/websocketpp EXCLUDE_FROM_ALL ) setup_library( fc SOURCES ${sources} LIBRARY_TYPE STATIC ) install( DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" DESTINATION include ) -# begin readline stuff -find_package(Curses) -find_package(Readline) - -file(GLOB HEADERS "include/bts/cli/*.hpp") - -if (READLINE_FOUND) - target_compile_definitions (fc PRIVATE HAVE_READLINE) - set(readline_libraries ${Readline_LIBRARY}) - if (CURSES_FOUND) - list(APPEND readline_libraries ${CURSES_LIBRARY}) - endif() - set(readline_includes ${Readline_INCLUDE_DIR}) -endif() +# begin editline stuff if(WIN32) target_compile_definitions( fc PRIVATE _CRT_NONSTDC_NO_DEPRECATE ) +else(WIN32) + target_compile_definitions( fc PRIVATE HAVE_EDITLINE ) + set( editline_libraries editline ) endif(WIN32) -# end readline stuff +# end editline stuff if( NOT CPP_STANDARD ) - set( CPP_STANDARD, "-std=c++11" ) + set( CPP_STANDARD "-std=c++11" ) endif() IF(WIN32) @@ -360,7 +398,6 @@ target_include_directories(fc ${OPENSSL_INCLUDE_DIR} "vendor/diff-match-patch-cpp-stl" ${CMAKE_CURRENT_SOURCE_DIR}/vendor/websocketpp - "${readline_includes}" PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp @@ -370,7 +407,7 @@ target_include_directories(fc IF(NOT WIN32) set(LINK_USR_LOCAL_LIB -L/usr/local/lib) ENDIF() -target_link_libraries( fc PUBLIC ${LINK_USR_LOCAL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library} ${readline_libraries} ${ECC_LIB} ) +target_link_libraries( fc PUBLIC ${LINK_USR_LOCAL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library} ${editline_libraries} ${ECC_LIB} ) if(MSVC) set_source_files_properties( src/network/http/websocket.cpp PROPERTIES COMPILE_FLAGS "/bigobj" ) diff --git a/CMakeModules/FindReadline.cmake b/CMakeModules/FindReadline.cmake deleted file mode 100755 index 745cfe5..0000000 --- a/CMakeModules/FindReadline.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# - Try to find readline include dirs and libraries -# -# Usage of this module as follows: -# -# find_package(Readline) -# -# Variables used by this module, they can change the default behaviour and need -# to be set before calling find_package: -# -# Readline_ROOT_DIR Set this variable to the root installation of -# readline if the module has problems finding the -# proper installation path. -# -# Variables defined by this module: -# -# READLINE_FOUND System has readline, include and lib dirs found -# Readline_INCLUDE_DIR The readline include directories. -# Readline_LIBRARY The readline library. - -find_path(Readline_ROOT_DIR - NAMES include/readline/readline.h -) - -find_path(Readline_INCLUDE_DIR - NAMES readline/readline.h - HINTS ${Readline_ROOT_DIR}/include -) - -find_library(Readline_LIBRARY - NAMES readline - HINTS ${Readline_ROOT_DIR}/lib -) - -if(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY) - set(READLINE_FOUND TRUE) -else(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY) - FIND_LIBRARY(Readline_LIBRARY NAMES readline) - include(FindPackageHandleStandardArgs) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG Readline_INCLUDE_DIR Readline_LIBRARY ) - MARK_AS_ADVANCED(Readline_INCLUDE_DIR Readline_LIBRARY) -endif(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY) - -mark_as_advanced( - Readline_ROOT_DIR - Readline_INCLUDE_DIR - Readline_LIBRARY -) diff --git a/src/rpc/cli.cpp b/src/rpc/cli.cpp index 4957fc3..89cdc8a 100755 --- a/src/rpc/cli.cpp +++ b/src/rpc/cli.cpp @@ -7,22 +7,8 @@ #include #endif -#ifdef HAVE_READLINE -# include -# include -// I don't know exactly what version of readline we need. I know the 4.2 version that ships on some macs is -// missing some functions we require. We're developing against 6.3, but probably anything in the 6.x -// series is fine -# if RL_VERSION_MAJOR < 6 -# ifdef _MSC_VER -# pragma message("You have an old version of readline installed that might not support some of the features we need") -# pragma message("Readline support will not be compiled in") -# else -# warning "You have an old version of readline installed that might not support some of the features we need" -# warning "Readline support will not be compiled in" -# endif -# undef HAVE_READLINE -# endif +#ifdef HAVE_EDITLINE +# include "editline.h" # ifdef WIN32 # include # endif @@ -131,61 +117,90 @@ void cli::run() } -char * dupstr (const char* s) { - char *r; - - r = (char*) malloc ((strlen (s) + 1)); - strcpy (r, s); - return (r); -} - -char* my_generator(const char* text, int state) +/**** + * @brief loop through list of commands, attempting to find a match + * @param token what the user typed + * @param match sets to 1 if only 1 match was found + * @returns the remaining letters of the name of the command or NULL if 1 match not found + */ +static char *my_rl_complete(char *token, int *match) { - static int list_index, len; - const char *name; - - if (!state) { - list_index = 0; - len = strlen (text); - } + bool have_one = false; + std::string method_name; auto& cmd = cli_commands(); + int partlen = strlen (token); /* Part of token */ - while( list_index < cmd.size() ) + for (const std::string& it : cmd) { - name = cmd[list_index].c_str(); - list_index++; - - if (strncmp (name, text, len) == 0) - return (dupstr(name)); + if (it.compare(0, partlen, token) == 0) + { + if (have_one) { + // we can only have 1, but we found a second + return NULL; + } + else + { + method_name = it; + have_one = true; + } + } } - /* If no names matched, then return NULL. */ - return ((char *)NULL); + if (have_one) + { + *match = 1; + method_name += " "; + return strdup (method_name.c_str() + partlen); + } + + return NULL; } - -static char** cli_completion( const char * text , int start, int end) +/*** + * @brief return an array of matching commands + * @param token the incoming text + * @param array the resultant array of possible matches + * @returns the number of matches + */ +static int cli_completion(char *token, char ***array) { - char **matches; - matches = (char **)NULL; + auto& cmd = cli_commands(); + int num_commands = cmd.size(); -#ifdef HAVE_READLINE - if (start == 0) - matches = rl_completion_matches ((char*)text, &my_generator); - else - rl_bind_key('\t',rl_abort); -#endif + char **copy = (char **) malloc (num_commands * sizeof(char *)); + if (copy == NULL) + { + // possible out of memory + return 0; + } + int total_matches = 0; - return (matches); + int partlen = strlen(token); + + for (const std::string& it : cmd) + { + if ( it.compare(0, partlen, token) == 0) + { + copy[total_matches] = strdup ( it.c_str() ); + ++total_matches; + } + } + *array = copy; + + return total_matches; } - +/*** + * @brief Read input from the user + * @param prompt the prompt to display + * @param line what the user typed + */ void cli::getline( const fc::string& prompt, fc::string& line) { // getting file descriptor for C++ streams is near impossible // so we just assume it's the same as the C stream... -#ifdef HAVE_READLINE +#ifdef HAVE_EDITLINE #ifndef WIN32 if( isatty( fileno( stdin ) ) ) #else @@ -197,8 +212,9 @@ void cli::getline( const fc::string& prompt, fc::string& line) if( _isatty( _fileno( stdin ) ) ) #endif { - rl_attempted_completion_function = cli_completion; - + rl_set_complete_func(my_rl_complete); + rl_set_list_possib_func(cli_completion); +jjkkljk; static fc::thread getline_thread("getline"); getline_thread.async( [&](){ char* line_read = nullptr; @@ -206,10 +222,17 @@ void cli::getline( const fc::string& prompt, fc::string& line) line_read = readline(prompt.c_str()); if( line_read == nullptr ) FC_THROW_EXCEPTION( fc::eof_exception, "" ); - rl_bind_key( '\t', rl_complete ); - if( *line_read ) - add_history(line_read); line = line_read; + try + { + if (*line_read) + add_history(line_read); + } + catch(...) + { + free(line_read); + throw; + } free(line_read); }).wait(); } diff --git a/vendor/editline/.gitignore b/vendor/editline/.gitignore new file mode 100644 index 0000000..0c5e288 --- /dev/null +++ b/vendor/editline/.gitignore @@ -0,0 +1,29 @@ +*~ +*/.libs/ +*.lo +*.o +*.pc +.deps +.testit_history +GPATH +GRTAGS +GTAGS +Makefile +Makefile.in +aclocal.m4 +archive +autom4te.cache +compile +config.guess +config.h +config.h.in +config.log +config.status +config.sub +configure +depcomp +install-sh +libtool +ltmain.sh +missing +stamp-h1 diff --git a/vendor/editline/.travis.yml b/vendor/editline/.travis.yml new file mode 100644 index 0000000..0e112fc --- /dev/null +++ b/vendor/editline/.travis.yml @@ -0,0 +1,34 @@ +# Travis CI integration +# Defaults to GNU GCC and autotools: ./configure && make && make test +language: c + +# We don't need to install packages, use dockerized build, quicker +sudo: false + +# Test build with both GCC and Clang (LLVM) +compiler: + - gcc + - clang + +env: + global: + # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created + # via the "travis encrypt" command using the project repo's public key + - secure: "iFll6pD0lzVYVRUlbPBGOTB0xqoEsC0BeUdftfRQdnEssruWOEKtf3VH6gSNRu8QMPeTCNhl4fsWUJhnowZgoobi/XcsXxFv/oJQZ1sa7cQUXizeEYUmsDZxUiw/sNsWlUz6dBKPepQStYyOK/tJLQ1GfLi1ESTPt6anokMVDbk=" + +addons: + coverity_scan: + project: + name: "troglobit/editline" + description: "A small line editing library" + notification_email: troglobit@gmail.com + build_command_prepend: "./autogen.sh && ./configure --enable-sigstop --enable-terminal-bell" + build_command: "make -j5" + branch_pattern: dev + +# We don't store generated files (configure and Makefile) in GIT, +# so we must customize the default build script to run ./autogen.sh +script: + - ./autogen.sh + - ./configure --enable-sigstop --enable-terminal-bell + - make -j5 diff --git a/vendor/editline/ChangeLog.md b/vendor/editline/ChangeLog.md new file mode 100644 index 0000000..59abbe6 --- /dev/null +++ b/vendor/editline/ChangeLog.md @@ -0,0 +1,241 @@ +Change Log +========== + +All notable changes to the project are documented in this file. + + +[1.16.1][UNRELEASED] +-------------------- + +### Changes +- Major updates to the `editline.3` man page + +### Fixes +- Fix #20: `configure --disable-eof` does not bite +- Fix #23: Make Ctrl-L clear the screan instead of starting a new line +- Fix #24: Fix behavior when TTY is narrower than column width, by Will Dietz + + +[1.16.0][] - 2018-09-16 +----------------------- + +Event loop callback support. + +### Changes +- `rl_unintialize()`, new function to free all memory, by Claus Fischer +- `rl_insert_text()`, new GNU Readline compat function +- `rl_refresh_line()`, new GNU Readline compat function +- `rl_callback_*()`, alternate interface to plain `readline()` for event + loops. Modeled after the GNU Readline API +- `rl_completion_entry_function`, and `rl_attempted_completion_function` + are two new GNU Readline compat user hooks for the completion framework +- `rl_completion_matches()` and `rl_filename_completion_function()` + are two new GNU Readline compat functions +- Add new example: `fileman.c` from GNU Readline to demonstrate the + level of compatibility of the revamped completion framework +- Add support for Ctrl-Right and Ctrl-Left, forward/backward word +- Add .deb package to official release target + +### Fixes +- Fixed header guards, avoid using leading `__` +- Spell check fixes +- Remove duplicate code in history check +- Use `NULL` instead of `0`, and `-1` instead of `NULL`, where applicable +- Misc. minor Coverity Scan fixes +- Misc. minor fixes to `testit.c` example code +- Add `-Wextra` to std `CFLAGS` +- Check `fclose()` return value in in `write_history()` and `read_history()` +- Initialize global variables and reset to `NULL` on `free()` +- Fix off-by-one in forward kill word, avoid deleting too much +- Skip (or kill) leading whitespace when skipping (or killing) forwards + + +[1.15.3][] - 2017-09-07 +----------------------- + +Bug fix release. + +### Changes +- Refactor all enable/disable configure options, same problem as in #7 + +### Fixes +- Fix #7: `--enable-termcap` configure option does not work. The script + enabled termcap by default rather than the other way around. + + Also, check for terminfo as well, when `--enable-termcap` is selected. + + +[1.15.2][] - 2016-06-06 +----------------------- + +Bug fixes and minor feature creep in `pkg-config` support. + +### Changes +- Prevent mangling of symbols when linking with C++. Patch courtesy of + Jakub Pawlowski +- Add `libeditline.pc` for `pkg-config` + +### Fixes +- Do not assume a termcap library exists, check for `tgetent()` in + curses, ncurses, tinfo and termcap libraries +- Call `tty_flush()` when user calls `rl_forced_update_display()` + to prevent screen becoming garbled. Patch by Jakub Pawlowski + + +[1.15.1][] - 2015-11-16 +----------------------- + +Bug fixes only. + +### Changes +- Update README with origin of this version of editline + +### Fixes +- Fix build system, don't force automake v1.11, require at least v1.11 +- Fix build problem with examples using `--enable-termcap` + + +[1.15.0][] - 2015-09-10 +----------------------- + +### Changes +- Add support for `--disable-eof` and `--disable-sigint` to disable + default Ctrl-D and Ctrl-C behavior +- Add support for `el_no_hist` to disable access to and auto-save of history +- GNU readline compat functions for prompt handling and redisplay +- Refactor: replace variables named 'new' with non-reserved word +- Add support for [Travis-CI][], continuous integration with GitHub +- Add support for [Coverity Scan][], the best static code analyzer, + integrated with [Travis-CI][] -- scan runs for each push to master +- Rename NEWS.md --> ChangeLog.md, with symlinks for make install +- Attempt to align with http://keepachangelog.com/ for this file +- Cleanup and improve Markdown syntax in [README.md][] +- Add API and example to [README.md][], inspired by [libuEv][] +- Removed generated files from version control. Use `./autogen.sh` + to generate the `configure` script when working from GIT. This + does not affect distributed tarballs + +### Fixes +- Fix issue #2, regression in Ctrl-D (EOF) behavior. Regression + introduced in [1.14.1][]. Fixed by @TobyGoodwin +- Fix memory leak in completion handler. Found by [Coverity Scan][]. +- Fix suspicious use of `sizeof(char **)`, same as `sizeof(char *)` but + non-portable. Found by [Coverity Scan][] +- Fix out-of-bounds access in user key binding routines + Found by [Coverity Scan][]. +- Fix invisible example code in man page + + +[1.14.2][] - 2014-09-14 +----------------------- + +Bug fixes only. + +### Fixes + - Fix `el_no_echo` bug causing secrets to leak when disabling no-echo + - Handle `EINTR` in syscalls better + + +[1.14.1][] - 2014-09-14 +----------------------- + +Minor fixes and additions. + +### Changes +- Don't print status message on `stderr` in key binding funcions +- Export `el_del_char()` +- Check for and return pending signals when detected +- Allow custom key bindings ... + +### Fixes +- Bug fixes ... + + +[1.14.0][] - 2010-08-10 +----------------------- + +Major cleanups and further merges with Debian editline package. + +### Changes +- Merge in changes to `debian/` from `editline_1.12-6.debian.tar.gz` +- Migrate to use libtool +- Make `UNIQUE_HISTORY` configurable +- Make scrollback history (`HIST_SIZE`) configurable +- Configure options for toggling terminal bell and `SIGSTOP` (Ctrl-Z) +- Configure option for using termcap to read/control terminal size +- Rename Signal to `el_intr_pending`, from Festival speech-tools +- Merge support for capitalizing words (`M-c`) from Festival + speech-tools by Alan W Black +- Fallback backspace handling, in case `tgetstr("le")` fails + +### Fixes +- Cleanups and fixes thanks to the Sparse static code analysis tool +- Merge `el_no_echo` patch from Festival speech-tools +- Merge fixes from Heimdal project +- Completely refactor `rl_complete()` and `rl_list_possib()` with + fixes from the Heimdal project. Use `rl_set_complete_func()` and + `rl_set_list_possib_func()`. Default completion callbacks are now + available as a configure option `--enable-default-complete` +- Memory leak fixes +- Actually fix 8-bit handling by reverting old Debian patch +- Merge patch to improve compatibility with GNU readline, thanks to + Steve Tell from way back in 1997 and 1998 + + +[1.13.0][] - 2010-03-09 +----------------------- + +Adaptations to Debian editline package. + +### Changes +- Major version number bump, adapt to Jim Studt's v1.12 +- Import `debian/` directory and adapt it to configure et al. +- Change library name to libeditline to distinguish it from BSD libedit + + +[0.3.0][] - 2009-02-08 +---------------------- + +### Changes +- Support for ANSI arrow keys using configure --enable-arrow-keys + + +[0.2.3][] - 2008-12-02 +---------------------- + +### Changes +- Patches from Debian package merged +- Support for custom command completion + + +[0.1.0][] - 2008-06-07 +---------------------- + +### Changes +- First version, forked from Minix current 2008-06-06 + + +[UNRELEASED]: https://github.com/troglobit/finit/compare/1.16.0...HEAD +[1.16.1]: https://github.com/troglobit/finit/compare/1.16.0...1.16.1 +[1.16.0]: https://github.com/troglobit/finit/compare/1.15.3...1.16.0 +[1.15.3]: https://github.com/troglobit/finit/compare/1.15.2...1.15.3 +[1.15.2]: https://github.com/troglobit/finit/compare/1.15.1...1.15.2 +[1.15.1]: https://github.com/troglobit/finit/compare/1.15.0...1.15.1 +[1.15.0]: https://github.com/troglobit/finit/compare/1.14.2...1.15.0 +[1.14.2]: https://github.com/troglobit/finit/compare/1.14.1...1.14.2 +[1.14.1]: https://github.com/troglobit/finit/compare/1.14.0...1.14.1 +[1.14.0]: https://github.com/troglobit/finit/compare/1.13.0...1.14.0 +[1.13.0]: https://github.com/troglobit/finit/compare/0.3.0...1.13.0 +[0.3.0]: https://github.com/troglobit/finit/compare/0.2.3...0.3.0 +[0.2.3]: https://github.com/troglobit/finit/compare/0.1.0...0.2.3 +[0.1.0]: https://github.com/troglobit/finit/compare/0.0.0...0.1.0 +[libuEv]: http://github.com/troglobit/libuev +[Travis-CI]: https://travis-ci.org/troglobit/uftpd +[Coverity Scan]: https://scan.coverity.com/projects/2947 +[README.md]: https://github.com/troglobit/editline/blob/master/README.md + + diff --git a/vendor/editline/INSTALL.md b/vendor/editline/INSTALL.md new file mode 100644 index 0000000..c54ed53 --- /dev/null +++ b/vendor/editline/INSTALL.md @@ -0,0 +1,46 @@ +HowTo Build Minix Editline +========================== + +Minix editline use the GNU configure tools, which includes autoconf, +automake and libtool. This enables high levels of portability and ease +of use. In most cases all you need to do is unpack the tarball, enter +the directory and type: + + ./configure + +There are are, however, more options available. For instance, sometimes +it is useful to build editline as a static library, type: + + ./configure --disable-shared + +By default editline employs a default handler for the TAB key, pressing +it once completes to the nearest matching filename in the current +working directory, or it can display a listing of possible completions. +For some uses this default is not desirable at all, type: + + ./configure --disable-default-complete + +An even more common desire is to change the default install location. +By default all configure scripts setup /usr/local as the install +"prefix", to change this type: + + ./configure --prefix=/home/troglobit/tmp + +Advanced users are encouraged to read up on --libdir, --mandir, etc. in +the GNU Configure and Build System. + +For more available options, type: + + ./configure --help + +To build and install, simply type: + + make + +followed by + + sudo make install + +Good Luck! + //Joachim + diff --git a/vendor/editline/LICENSE b/vendor/editline/LICENSE new file mode 100644 index 0000000..1c0d909 --- /dev/null +++ b/vendor/editline/LICENSE @@ -0,0 +1,18 @@ + Copyright 1992,1993 Simmule Turner and Rich Salz + All rights reserved. + + This software is not subject to any license of the American Telephone + and Telegraph Company or of the Regents of the University of California. + + Permission is granted to anyone to use this software for any purpose on + any computer system, and to alter it and redistribute it freely, subject + to the following restrictions: + 1. The authors are not responsible for the consequences of use of this + software, no matter how awful, even if they arise from flaws in it. + 2. The origin of this software must not be misrepresented, either by + explicit claim or by omission. Since few users ever read sources, + credits must appear in the documentation. + 3. Altered versions must be plainly marked as such, and must not be + misrepresented as being the original software. Since few users + ever read sources, credits must appear in the documentation. + 4. This notice may not be removed or altered. diff --git a/vendor/editline/Make.os9 b/vendor/editline/Make.os9 new file mode 100644 index 0000000..c632847 --- /dev/null +++ b/vendor/editline/Make.os9 @@ -0,0 +1,19 @@ +## $Revision: 1.2 $ +## +## OS-9 makefile for editline library. +## + +.SUFFIXES: + +RFILES = editline.r complete.r sysos9.r + +%.r: %.c + cc68 -r -Dstrchr=index -Dstrrchr=rindex -DNEED_STRDUP -DSYS_OS9 $*.c + +testit: testit.r editline.lib + cc68 -f=testit testit.r -l=editline.lib + +$(RFILES): $(RFILES:%.r=%.c) + +editline.lib: $(RFILES) + cat $(RFILES) >$@ diff --git a/vendor/editline/Makefile.am b/vendor/editline/Makefile.am new file mode 100644 index 0000000..0342154 --- /dev/null +++ b/vendor/editline/Makefile.am @@ -0,0 +1,52 @@ +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libeditline.pc +doc_DATA = README.md LICENSE +EXTRA_DIST = README.md LICENSE ChangeLog.md INSTALL.md +SUBDIRS = src include man examples + +## Generate .deb package +package build-deb: + @dpkg-buildpackage -uc -us + +## Generate MD5 checksum file +MD5 = md5sum +md5-dist: + @for file in $(DIST_ARCHIVES); do \ + $(MD5) $$file > ../$$file.md5; \ + mv $$file ../; \ + done + +## Check if tagged in git +release-hook: + if [ ! `git tag | grep $(PACKAGE_VERSION)` ]; then \ + echo; \ + printf "\e[1m\e[41mCannot find release tag $(PACKAGE_VERSION)\e[0m\n"; \ + printf "\e[1m\e[5mDo release anyway?\e[0m "; read yorn; \ + if [ "$$yorn" != "y" -a "$$yorn" != "Y" ]; then \ + printf "OK, aborting release.\n"; \ + exit 1; \ + fi; \ + echo; \ + else \ + echo; \ + printf "\e[1m\e[42mFound GIT release tag $(PACKAGE_VERSION)\e[0m\n"; \ + printf "\e[1m\e[44m>>Remember to push tags!\e[0m\n"; \ + echo; \ + fi + +# lintian --profile debian -i -I --show-overrides ../$PKG.changes +package: + dpkg-buildpackage -uc -us -B + +## Target to run when building a release +release: distcheck release-hook md5-dist package + @echo + @echo "Resulting release files:" + @echo "=========================================================================" + @for file in $(DIST_ARCHIVES); do \ + printf "%-40s Distribution tarball\n" $$file; \ + printf "%-40s " $$file.md5; cat ../$$file.md5 | cut -f1 -d' '; \ + done + @for file in `cd ..; ls *$(PACKAGE)*_$(subst _,.,$(VERSION))*`; do \ + printf "%-40s Debian/Ubuntu package file\n" $$file; \ + done diff --git a/vendor/editline/README.md b/vendor/editline/README.md new file mode 100644 index 0000000..2e27552 --- /dev/null +++ b/vendor/editline/README.md @@ -0,0 +1,271 @@ +Editline +======== +[![License Badge][]][License] [![Travis Status]][Travis] [![Coverity Status]][Coverity Scan] + + +Table of Contents +----------------- + +* [Introduction](#introduction) +* [API](#api) +* [Example](#example) +* [Build & Install](#build--install) +* [Origin & References](#origin--references) + + +Introduction +------------ + +This is a small [line editing][] library. It can be linked into almost +any program to provide command line editing and history functions. It +is call compatible with the [FSF readline][] library, but at a fraction +of the size, and as a result fewer features. It is also distributed +under a much more liberal [License][]. + +The small size (<30k), lack of dependencies (ncurses not needed!), and +the free license should make this library interesting to many embedded +developers. + +Editline has several optional build-time features that can be enabled by +supplying different options to the GNU configure script. See the output +from configure --help for details. Some useful hints on how +to use the library is available in the `examples/` directory. + +Editline is maintained collaboratively at [GitHub][]. + + +Example +------- + +Below follows a brief example to illustrate how one can use Editline to +create a simple CLI, use Ctrl-D to exit the program. For a slightly +more advanced example, see . The +Editline sources also include an `examples/` sub-directory. + +1. Build and install the library, preferably using a [release tarball][] + The configure script defaults to a `/usr/local` prefix. + + tar xf editline-1.15.3.tar.xz + cd editline-1.15.3/ + ./configure --prefix=/usr + make all + sudo make install + +2. Place the below source code in a separate project directory, + e.g. `~/src/example.c` + +```C + #include + #include + + int main(void) + { + char *p; + + while ((p = readline("CLI> ")) != NULL) { + puts(p); + free(p); + } + + return 0; + } +``` + +3. Compile the example: + + cd ~/src/ + make LDLIBS=-leditline example + +Here I use `make` and rely on its implicit (built-in) rules to handle +all the compiler magic, but you may want to create your own Makefile for +the project. In particular if you don't change the default prefix +(above), because then you need to specify the search path for the +include file(s) and the library manually. + +A simple `~/src/Makefile` could look like this: + + CFLAGS = -I/usr/local/include + LDFLAGS = -L/usr/local/lib + LDLIBS = -leditline + EXEC = example + OBJS = example.o + + all: $(EXEC) + + $(EXEC): $(OBJS) + + clean: + $(RM) $(OBJS) $(EXEC) + + distclean: clean + $(RM) *.o *~ *.bak + +Then simply type `make` from your `~/src/` directory. You can also use +`pkg-config` for your `~/src/Makefile`, replace the following lines: + + CFLAGS = $(shell pkg-config --cflags libeditline) + LDFLAGS = $(shell pkg-config --libs-only-L libeditline) + LDLIBS = $(shell pkg-config --libs-only-l libeditline) + +Then simply type make, like above. + +However, most `.rpm` based distributions `pkg-config` doesn't search in +`/usr/local` anymore, so you need to call make like this: + + PKG_CONFIG_LIBDIR=/usr/local/lib/pkgconfig make + +Debian/Ubuntu based systems do not have this problem. + + +API +--- + +Here is the libeditline interfaces. It has a small compatibility layer +to [FSF readline][], which may not be entirely up-to-date. + +```C + /* Editline specific global variables. */ + int el_no_echo; /* Do not echo input characters */ + int el_no_hist; /* Disable auto-save of and access to history, + * e.g. for password prompts or wizards */ + int el_hist_size; /* Size of history scrollback buffer, default: 15 */ + + /* Editline specific functions. */ + char * el_find_word (void); + void el_print_columns (int ac, char **av); + el_status_t el_ring_bell (void); + el_status_t el_del_char (void); + + /* Callback function for key binding */ + typedef el_status_t el_keymap_func_t(void); + + /* Bind key to a callback, use CTL('f') to change Ctrl-F, for example */ + el_status_t el_bind_key (int key, el_keymap_func_t function); + el_status_t el_bind_key_in_metamap (int key, el_keymap_func_t function); + + /* For compatibility with FSF readline. */ + int rl_point; + int rl_mark; + int rl_end; + int rl_inhibit_complete; + char *rl_line_buffer; + const char *rl_readline_name; + + void (*rl_deprep_term_function)(void); + void rl_deprep_terminal (void); + void rl_reset_terminal (const char *terminal_name); + + void rl_initialize (void); + void rl_uninitialize (void); /* Free all internal memory */ + + void rl_save_prompt (void); + void rl_restore_prompt (void); + void rl_set_prompt (const char *prompt); + + void rl_clear_message (void); + void rl_forced_update_display (void); + + /* Main function to use, saves history by default */ + char *readline (const char *prompt); + + /* Use to save a read line to history, when el_no_hist is set */ + void add_history (const char *line); + + /* Load and save editline history from/to a file. */ + int read_history (const char *filename); + int write_history (const char *filename); + + /* Magic completion API, see examples/cli.c for more info */ + rl_complete_func_t *rl_set_complete_func (rl_complete_func_t *func); + rl_list_possib_func_t *rl_set_list_possib_func (rl_list_possib_func_t *func); + + /* Alternate interface to plain readline(), for event loops */ + void rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *lhandler); + void rl_callback_read_char (void); + void rl_callback_handler_remove (void); +``` + + +Build & Install +--------------- + +Editline was originally designed for older UNIX systems and Plan 9. The +current maintainer works exclusively on GNU/Linux systems, so it may use +GCC and GNU Make specific extensions here and there. This is not on +purpose and patches or pull requests to correct this are most welcome! + +1. Configure editline with default features: ./configure +2. Build the library and examples: make all +3. Install using make install + +The `$DESTDIR` environment variable is honored at install. For more +options, see ./configure --help + +Remember to run `ldconfig` after install to update the linker cache. If +you've installed to a non-standard location (`--prefix`) you may also +have to update your `/etc/ld.so.conf`, or use `pkg-confg` to build your +application (above). + +**NOTE:** RedHat/Fedora/CentOS and other `.rpm`-based distributions do + not consider `/usr/local` as standard path anymore. So make sure to + `./configure --prefix=/usr`, otherwise the build system use the GNU + default, which is `/usr/local`. The Debian based distributions, like + Ubuntu, do not have this problem. + + +Origin & References +-------------------- + +This [line editing][] library was created by [Rich Salz][] and Simmule +Turner and in 1992. It is distributed with a “[C News][]-like” license, +similar to the [BSD license][]. Rich's current version is however under +the Apache license. For details on the licensing terms of this version +of the software, see [License][]. + +This version of the editline library was forked from the [Minix 2][] +source tree and is *not* related to the similarily named NetBSD version +that [Jess Thrysøe][jess] disitributes to the world outside *BSD. The +libraries have much in common, but the latter is heavily refactored and +also relies on libtermcap (usually supplied by ncurses), whereas this +library only uses termios from the standard C library. + +Patches and bug fixes from the following forks, based on the original +[comp.sources.unix][] posting, have been merged: + +* Debian [libeditline][] +* [Heimdal][] +* [Festival][] speech-tools +* [Steve Tell][]'s editline patches + +The version numbering scheme today follows that of the Debian version, +details available in the [ChangeLog.md][]. The current [maintainer][] +was unaware of the Debian version for quite some time, so a different +name and versioning scheme was used. In June 2009 this was changed to +line up alongside Debian, with the intent is to eventually merge the +efforts. + +Outstanding issues are listed in the [TODO.md][] file. + +[GitHub]: https://github.com/troglobit/editline +[line editing]: https://github.com/troglobit/editline/blob/master/docs/README +[release tarball]: https://github.com/troglobit/editline/releases +[maintainer]: http://troglobit.com +[C News]: https://en.wikipedia.org/wiki/C_News +[TODO.md]: https://github.com/troglobit/editline/blob/master/docs/TODO.md +[ChangeLog.md]: https://github.com/troglobit/editline/blob/master/ChangeLog.md +[FSF readline]: http://www.gnu.org/software/readline/ +[Rich Salz]: https://github.com/richsalz/editline/ +[comp.sources.unix]: http://ftp.cs.toronto.edu/pub/white/pub/rc/editline.shar +[Minix 2]: http://www.cise.ufl.edu/~cop4600/cgi-bin/lxr/http/source.cgi/lib/editline/ +[jess]: http://thrysoee.dk/editline/ +[BSD license]: http://en.wikipedia.org/wiki/BSD_licenses +[libeditline]: http://packages.qa.debian.org/e/editline.html +[Heimdal]: http://www.h5l.org +[Festival]: http://festvox.org/festival/ +[Steve Tell]: http://www.cs.unc.edu/~tell/dist.html +[License]: https://github.com/troglobit/editline/blob/master/LICENSE +[License Badge]: https://img.shields.io/badge/License-C%20News-orange.svg +[Travis]: https://travis-ci.org/troglobit/editline +[Travis Status]: https://travis-ci.org/troglobit/editline.png?branch=master +[Coverity Scan]: https://scan.coverity.com/projects/2982 +[Coverity Status]: https://scan.coverity.com/projects/2982/badge.svg diff --git a/vendor/editline/autogen.sh b/vendor/editline/autogen.sh new file mode 100755 index 0000000..dbbcad3 --- /dev/null +++ b/vendor/editline/autogen.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +autoreconf -W portability -visfm diff --git a/vendor/editline/configure.ac b/vendor/editline/configure.ac new file mode 100644 index 0000000..0e03d24 --- /dev/null +++ b/vendor/editline/configure.ac @@ -0,0 +1,99 @@ +AC_INIT(editline, 1.16.1-dev, https://github.com/troglobit/editline/issues) +AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz]) +AM_SILENT_RULES([yes]) + +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_SRCDIR([src/editline.c]) +AC_CONFIG_HEADER([config.h]) +AC_CONFIG_FILES([Makefile libeditline.pc src/Makefile include/Makefile man/Makefile examples/Makefile]) + +# Checks for programs. +AC_PROG_CC +AC_PROG_INSTALL + +# Checks for libraries. +LT_INIT + +# Checks for header files. +AC_HEADER_DIRENT +AC_HEADER_STAT +AC_HEADER_STDC +# Check for malloc.h instead of AC_FUNC_MALLOC/REALLOC AIX and others +# mess up the traditional malloc check. +AC_CHECK_HEADERS([malloc.h signal.h stdlib.h string.h termcap.h termio.h termios.h sgtty.h unistd.h]) + +# In termios.h or in sys/ioctl.g? +AC_HEADER_TIOCGWINSZ + +# Overrides and types, should be a check. +AC_DEFINE([SYS_UNIX], [1], [Default to UNIX backend, should be detected.]) +AC_TYPE_SIZE_T + +# Checks for library functions. +AC_FUNC_CLOSEDIR_VOID +AC_PROG_GCC_TRADITIONAL +AC_FUNC_STAT +AC_CHECK_FUNCS([strchr strdup strrchr tcgetattr perror]) + +# +# Available features +# +AC_ARG_ENABLE(unique-history, + [AS_HELP_STRING([--disable-unique-history], + [Disable uniqify of scrollback. Default: duplicate entries are ignored. Use this to save dupes.])]) + +AC_ARG_ENABLE(arrow-keys, + [AS_HELP_STRING([--disable-arrow-keys], [Disable ANSI arrow keys.])]) + +AC_ARG_ENABLE(eof, + [AS_HELP_STRING([--disable-eof], [Disable default EOF (Ctrl-D) behavior.])]) + +AC_ARG_ENABLE(sigint, + [AS_HELP_STRING([--disable-sigint], [Disable default SIGINT (Ctrl-C) behavior.])]) + +AC_ARG_ENABLE(sigstop, + [AS_HELP_STRING([--enable-sigstop], [Enable SIGSTOP (Ctrl-Z) behavior.])]) + +AC_ARG_ENABLE(terminal-bell, + [AS_HELP_STRING([--enable-terminal-bell], [Enable terminal bell on completion.])]) + +AC_ARG_ENABLE(termcap, + AS_HELP_STRING([--enable-termcap], [Use termcap library to query terminal size.])) + +# +# Check what features have been enabled +# +AS_IF([test "x$enable_unique_history" != "xno"], + AC_DEFINE(CONFIG_UNIQUE_HISTORY, 1, [Define to skip duplicate lines in the scrollback history.])) + +AS_IF([test "x$enable_terminal_bell" != "xno"], + AC_DEFINE(CONFIG_ANSI_ARROWS, 1, [Define to include ANSI arrow keys support.])) + +AS_IF([test "x$enable_eof" != "xno"], + AC_DEFINE(CONFIG_EOF, 1, [Define to enable EOF (Ctrl-D) key.])) + +AS_IF([test "x$enable_sigint" != "xno"], + AC_DEFINE(CONFIG_SIGINT, 1, [Define to enable SIGINT (Ctrl-C) key.])) + +AS_IF([test "x$enable_sigstop" = "xyes"], + AC_DEFINE(CONFIG_SIGSTOP, 1, [Define to enable SIGSTOP (Ctrl-Z) key.])) + +AS_IF([test "x$enable_terminal_bell" = "xyes"], + AC_DEFINE(CONFIG_TERMINAL_BELL, 1, [Define to enable terminal bell on completion.])) + +# Check for a termcap compatible library if enabled +AS_IF([test "x$enable_termcap" = "xyes"], + AC_DEFINE(CONFIG_USE_TERMCAP, 1, [Define to use the termcap library for terminal size.]) + AC_CHECK_LIB(terminfo, tgetent, , [ + AC_CHECK_LIB(termcap, tgetent, , [ + AC_CHECK_LIB(tinfo, tgetent, , [ + AC_CHECK_LIB(curses, tgetent, , [ + AC_CHECK_LIB(ncurses, tgetent, , [ + AC_MSG_ERROR([Cannot find a termcap capable library, try installing Ncurses.])]) + ]) + ]) + ]) + ])) + +# Generate all files +AC_OUTPUT diff --git a/vendor/editline/debian/.gitignore b/vendor/editline/debian/.gitignore new file mode 100644 index 0000000..8afbb05 --- /dev/null +++ b/vendor/editline/debian/.gitignore @@ -0,0 +1,10 @@ +*.log +*.debhelper +*.substvars +autoreconf.* +debhelper-build-stamp +files +tmp/* +libeditline-dev/* +libeditline0/* +libeditline1/* diff --git a/vendor/editline/debian/README.Debian b/vendor/editline/debian/README.Debian new file mode 100644 index 0000000..7380abd --- /dev/null +++ b/vendor/editline/debian/README.Debian @@ -0,0 +1,9 @@ +editline for Debian +---------------------- + +This is packaged in typical Debian form with a shared library version and +a static library version. It will be a rare package that wishes to +use the shared library form, the static one is only adds about 12.5kb +to your program. + + -- Jim Studt , Fri, 5 May 2000 13:25:51 -0500 diff --git a/vendor/editline/debian/changelog b/vendor/editline/debian/changelog new file mode 100644 index 0000000..5234f9d --- /dev/null +++ b/vendor/editline/debian/changelog @@ -0,0 +1,122 @@ +editline (1.16.1) unstable; urgency=medium + + * Minor bug fix and documentation update release. + + -- Joachim Nilsson Sat, 27 Apr 2019 15:01:07 +0200 + +editline (1.16.0) unstable; urgency=medium + + * New upstream release, v1.60.0 + + Event loop support + + New GNU Readline compat functions and callbacks + + Minor compat fixes for movement and deletion + * Bump .so/ABI version => libeditline1 + * New maintainer, upstream author + + -- Joachim Nilsson Sun, 16 Sep 2018 09:45:53 +0200 + +editline (1.15.3-1) unstable; urgency=medium + + * New upstream bug fix release, v1.15.3 + + -- Joachim Nilsson Thu, 07 Sep 2017 01:24:19 +0200 + +editline (1.15.2-1) unstable; urgency=medium + + * New upstream bug fix release, v1.15.2 + + -- Joachim Nilsson Wed, 06 Jun 2016 20:04:35 +0200 + +editline (1.15.1-1) unstable; urgency=medium + + * New upstream bug fix release, v1.15.1 + + -- Joachim Nilsson Wed, 16 Nov 2015 21:17:17 +0200 + +editline (1.15.0-1) unstable; urgency=medium + + * New upstream release, v1.15.0 + + -- Joachim Nilsson Wed, 10 Sep 2015 13:26:03 +0200 + +editline (1.14.2-1) unstable; urgency=low + + * Minor bugfix release: + + Fix `el_no_echo` bug causing secrets to leak when disabling no-echo + + Handle `EINTR` in syscalls better + + -- Joachim Nilsson Sun, 14 Sep 2014 04:27:25 +0200 + +editline (1.14.1-1) unstable; urgency=low + + * New release. + + Minor fixes to key binding. + + Check signals and custom keys before acting on them in readline(). + + Update maintainer email address. + + -- Joachim Nilsson Mon, 8 Jul 2013 17:04:00 +0100 + +editline (1.14.0-1) unstable; urgency=low + + * Update to new configure based build. + + -- Joachim Nilsson Wed, 11 Aug 2010 13:28:00 +0100 + +editline (1.12-6) unstable; urgency=low + + * Switch package format to 3.0 (quilt). + * 200_fix-truncation-at-64-char.diff: fix invalid 64-char truncation in + batch mode, courtesy of Mark O'Donohue. Thanks to Damyan Ivanov for + forwarding the patch from Ubuntu (Closes: #508640). + + -- Sam Hocevar Sun, 03 Jan 2010 15:45:34 +0100 + +editline (1.12-5) unstable; urgency=low + + * New maintainer (Closes: #229962). + * debian/changelog: + + Removed emacs helper variables. + * debian/control: + + Set policy to 3.6.1.0. + + Set debhelper build dependency to (>= 4.0). + + Use the default dh_shlibs information, since the API is rock stable + (Closes: #131139). + + Removed the libc6-dev dependency in the -dev package. + + Rephrased the short and long descriptions. + * debian/copyright: + + Replaced "Author(s)" with "Author". + * debian/rules: + + Removed obsolete call to dh_suidregister. + + Use debian/compat instead of DH_COMPAT. + * include_editline.h: + + Added a minimalist /usr/include/editline.h (Closes: #129544). + * Makefile: + + Call libtool with the proper --mode flags. + + -- Sam Hocevar (Debian packages) Sat, 31 Jan 2004 22:32:35 +0100 + +editline (1.12-4) unstable; urgency=low + + * Add a Build-Depends for debhelper and libtool. Thought those + were baseline. closes: #117780 + + -- Jim Studt Thu, 15 Nov 2001 19:00:00 -0600 + +editline (1.12-3) unstable; urgency=low + + * Make man pages not be in the shared library package. + + -- Jim Studt Sat, 13 Jan 2001 00:03:53 -0600 + +editline (1.12-2) unstable; urgency=low + + * Patch to not declare read() and write(), it fails on alphas. + + -- Jim Studt Tue, 12 Sep 2000 16:39:34 -0500 + +editline (1.12-1) unstable; urgency=low + + * Initial Release. + + -- Jim Studt Fri, 5 May 2000 13:25:51 -0500 + diff --git a/vendor/editline/debian/compat b/vendor/editline/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/vendor/editline/debian/compat @@ -0,0 +1 @@ +9 diff --git a/vendor/editline/debian/control b/vendor/editline/debian/control new file mode 100644 index 0000000..9687937 --- /dev/null +++ b/vendor/editline/debian/control @@ -0,0 +1,31 @@ +Source: editline +Section: devel +Priority: optional +Build-Depends: debhelper (>= 5.0), libtool +Maintainer: Joachim Nilsson +Standards-Version: 3.8.3 + +Package: libeditline-dev +Architecture: any +Section: libdevel +Depends: libeditline1 (= ${binary:Version}), ${misc:Depends} +Description: development files for libeditline + This is a line-editing library. It can be linked into almost any program + to provide command-line editing and recall. It is call-compatible with a + subset of the FSF readline library, but it is a fraction of the size (and + offers fewer features). + . + This package contains the developer files: static libraries, headers, + manpages. + +Package: libeditline1 +Architecture: any +Section: libs +Depends: ${misc:Depends} +Description: line editing library similar to readline + This is a line-editing library. It can be linked into almost any program + to provide command-line editing and recall. It is call-compatible with a + subset of the FSF readline library, but it is a fraction of the size (and + offers fewer features). + . + This package contains the runtime library only. diff --git a/vendor/editline/debian/copyright b/vendor/editline/debian/copyright new file mode 100644 index 0000000..10afa37 --- /dev/null +++ b/vendor/editline/debian/copyright @@ -0,0 +1,27 @@ +This package was debianized by Jim Studt on +Fri, 5 May 2000 13:25:51 -0500. + +It was received from Rich Salz rsalz@shore.net + +Upstream Author: Rich Salz rsalz@shore.net + +Copyright: + + Copyright 1992,1993 Simmule Turner and Rich Salz. All rights reserved. + + This software is not subject to any license of the American Telephone + and Telegraph Company or of the Regents of the University of California. + + Permission is granted to anyone to use this software for any purpose on + any computer system, and to alter it and redistribute it freely, subject + to the following restrictions: + 1. The authors are not responsible for the consequences of use of this + software, no matter how awful, even if they arise from flaws in it. + 2. The origin of this software must not be misrepresented, either by + explicit claim or by omission. Since few users ever read sources, + credits must appear in the documentation. + 3. Altered versions must be plainly marked as such, and must not be + misrepresented as being the original software. Since few users + ever read sources, credits must appear in the documentation. + 4. This notice may not be removed or altered. + diff --git a/vendor/editline/debian/dirs b/vendor/editline/debian/dirs new file mode 100644 index 0000000..4418816 --- /dev/null +++ b/vendor/editline/debian/dirs @@ -0,0 +1,2 @@ +usr/lib +usr/include diff --git a/vendor/editline/debian/docs b/vendor/editline/debian/docs new file mode 100644 index 0000000..b43bf86 --- /dev/null +++ b/vendor/editline/debian/docs @@ -0,0 +1 @@ +README.md diff --git a/vendor/editline/debian/libeditline-dev.install b/vendor/editline/debian/libeditline-dev.install new file mode 100644 index 0000000..9667918 --- /dev/null +++ b/vendor/editline/debian/libeditline-dev.install @@ -0,0 +1,4 @@ +usr/include/*.h +usr/lib/*/libeditline*.*a +usr/lib/*/pkgconfig/* +usr/share/man/man3/* diff --git a/vendor/editline/debian/libeditline0.install b/vendor/editline/debian/libeditline0.install new file mode 100644 index 0000000..b31f51e --- /dev/null +++ b/vendor/editline/debian/libeditline0.install @@ -0,0 +1 @@ +usr/lib/*/libeditline*.so* diff --git a/vendor/editline/debian/rules b/vendor/editline/debian/rules new file mode 100755 index 0000000..19ddb34 --- /dev/null +++ b/vendor/editline/debian/rules @@ -0,0 +1,8 @@ +#!/usr/bin/make -f + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +%: + dh $@ --with autoreconf + diff --git a/vendor/editline/debian/source/format b/vendor/editline/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/vendor/editline/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/vendor/editline/docs/HACKING.md b/vendor/editline/docs/HACKING.md new file mode 100644 index 0000000..0ced854 --- /dev/null +++ b/vendor/editline/docs/HACKING.md @@ -0,0 +1,106 @@ +Maintenance and Release Checklist +================================= + +Maintenance +----------- + +* Encourage contributors to write tests, in particular for new features +* Run tests regularly, use Travis-CI to do this automatically +* Leverage GitHub issues for milestone planning +* Reference issues from GitHub pull requests to alert issue subscribers +* Bump library ABI version just before release! + + +Release Checklist +----------------- + +* Update ChangeLog, follow http://keepachangelog.com/ loosely + - Inform users in a plain language of changes and bug fixes + - Do *not* copy-paste GIT commit logs! + - Order entries according to importance, most relevant first +* Run unit tests: `make check` +* Make at least one `-rcN` release and test it in an actual real project +* **REMEMBER:** bump ABI version according to below rules +* Tag +* Push last commit(s) *and* tags to GitHub +* Make release + + make distclean + ./autogen.sh + ./configure + make release + +* Create new release in GitHub releases page +* Copy and paste ChangeLog entry, check any stale links! +* Upload release tarball and MD5 files + + +Library Versioning +------------------ + +Editline relies on GNU Libtool for building the library. For a user of +the library it is important to maintain a clear ABI versioning scheme. +This is not the same as the Editline version, but rather the library +"compatibility level". + +The Editline ABI version is specified in `src/Makefile.am` and looks +like this: + + libeditline_la_LDFLAGS = -version-info 0:0:0 + \ \ `-- age + \ `--- revision + `---- current + +It must be updated according to the [GNU Libtool recommendations][1]: + +1. Start with version information of `0:0:0` for each libtool library. +2. Update the version information only immediately before a public + release of your software. More frequent updates are unnecessary, and + only guarantee that the current interface number gets larger faster. +3. If the library *source code has changed at all* since the last update, + then increment revision (`c:r:a` becomes `c:r+1:a`). +4. If any *interfaces have been added, removed, or changed* since the + last update, increment current, and set revision to 0. +5. If any *interfaces have been added* since the last public release, + then increment age. +6. If any *interfaces have been removed or changed* since the last + public release, then set age to 0. + +The libtool ABI versioning logic is very confusing but works if you just +disable your brain and follow the rules, one by one. + +**Example #1:** a new function has been added, none of the existing ones +have changed. The initial version is 1:0:0, we follow the rules above to +the letter: increase revision, increase current and set revision to zero, +and finally increase age. This, rather confusingly, gives us 2:0:1 which +libtool then translates to `libeditline.so.1.1.0`. + +**Example #2:** some existing functions are changed, they now return an +`int` instead of `void`. The initial version is 0:0:0, and we follow the +rules again: increment revision, increment current and set revision to +zero, set age to zero. This gives us 1:0:0, which is then translated to + `libeditline.so.1.0.0`. + +### Note + +Usually, non-developers have no interest in running development versions +(releases are frequent enough), and developers are expected to know how +to juggle versions. In such an ideal world, it is good enough to bump +the library version just prior to a release, point 2. + +However, if releases are few and far between, distributors may start to +use snapshots. When a distributor uses a snapshot, the distributor has +to handle the library version manually. Things can get ugly when the +distributor has released an intermediate version with a bumped library +version, and when the official release is bumped to that version, the +distributor will then have to bump the library version for the official +release, and it can be confusing if someone reports bugs on versions +that you didn't even know existed. + +The problem with bumping the version with every change is that if your +interface is not finished, the version number might run away, and it +looks pretty bad if a library is at version 262. It kind of tells the +user that the library interface is volatile, which is not good for +business. + +[1]: https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html diff --git a/vendor/editline/docs/README b/vendor/editline/docs/README new file mode 100755 index 0000000..c2d987f --- /dev/null +++ b/vendor/editline/docs/README @@ -0,0 +1,68 @@ +Original Minix README +===================== + +Below is the original Minix editline README file. It has been +split into a modified README and LICENSE file. + + -- Joachim Nilsson, June 7th 2008 + +----------------------------------------------------------------- +$Revision: 5 $ + +This is a line-editing library. It can be linked into almost any +program to provide command-line editing and recall. + +It is call-compatible with the FSF readline library, but it is a +fraction of the size (and offers fewer features). It does not use +standard I/O. It is distributed under a "C News-like" copyright. + +Configuration is done in the Makefile. Type "make testit" to get +a small slow shell for testing. + +An earlier version was distributed with Byron's rc. Principal +changes over that version include: + Faster. + Is eight-bit clean (thanks to brendan()cs!widener!edu) + Written in K&R C, but ANSI compliant (gcc all warnings) + Propagates EOF properly; rc trip test now passes + Doesn't need or use or provide memmove. + More robust + Calling sequence changed to be compatible with readline. + Test program, new manpage, better configuration + More system-independant; includes Unix and OS-9 support. + +This contains some changes since the posting to comp.sources.misc: + Bugfix for completion on absolute pathnames. + Better handling of M-n versus showing raw 8bit chars. + Better signal handling. + Now supports termios/termio/sgttyb ioctl's. + Add M-m command to toggle how 8bit data is displayed. + +There is one known bug: + History-searching redraws the line wrong if the text + retrieved is shorter then the prompt. + +Enjoy, + Rich $alz + + + Copyright 1992,1993 Simmule Turner and Rich Salz. All rights reserved. + + This software is not subject to any license of the American Telephone + and Telegraph Company or of the Regents of the University of California. + + Permission is granted to anyone to use this software for any purpose on + any computer system, and to alter it and redistribute it freely, subject + to the following restrictions: + 1. The authors are not responsible for the consequences of use of this + software, no matter how awful, even if they arise from flaws in it. + 2. The origin of this software must not be misrepresented, either by + explicit claim or by omission. Since few users ever read sources, + credits must appear in the documentation. + 3. Altered versions must be plainly marked as such, and must not be + misrepresented as being the original software. Since few users + ever read sources, credits must appear in the documentation. + 4. This notice may not be removed or altered. + +-- +$PchId: README,v 1.3 1996/02/22 21:18:51 philip Exp $ diff --git a/vendor/editline/docs/TODO.md b/vendor/editline/docs/TODO.md new file mode 100644 index 0000000..df60dc1 --- /dev/null +++ b/vendor/editline/docs/TODO.md @@ -0,0 +1,41 @@ +TODO +==== + +Issues in need of work. Mostly compatibility with GNU readline, +BSD [libedit][], and usability improvements. + +Remember, the general idea is to keep this library small with no +external dependencies, except for a generic C library. + + +Check what's needed to run the fileman example +---------------------------------------------- + +The BSD libedit library has imported the GNU readline "fileman" example +into its tree to demonstrate the abilities of that library. This would +also be quite useful for this library! + +The first task is to investigate the depependencies and form TODO list +items detailing what is missing and, if possible, proposals how to +implement including any optional configure flags. + + +Other minor TODO's +------------------ + +- Instead of supporting multiline input, try the Emacs approach, line + scrolling. +- Add support for `rl_bind_key()`, currently only en editline specific + `el_bind_key()` exists. +- Make `char *rl_prompt;` globally visible. +- Add support for `rl_set_prompt()` +- Add support for `--enable-utf8` to configure script +- Use `strcmp(nl_langinfo(CODESET), "UTF-8")` to look for utf8 capable + terminal +- Implement simple UTF-8 parser according to + http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + + +[gnu]: http://www.delorie.com/gnu/docs/readline/rlman_41.html#IDX288 +[libuEv]: https://github.com/troglobit/libuev/ +[libedit]: http://www.thrysoee.dk/editline/ diff --git a/vendor/editline/examples/.gitignore b/vendor/editline/examples/.gitignore new file mode 100644 index 0000000..bcb1d97 --- /dev/null +++ b/vendor/editline/examples/.gitignore @@ -0,0 +1,5 @@ +*.o +cli +testit +excallback +fileman diff --git a/vendor/editline/examples/Makefile.am b/vendor/editline/examples/Makefile.am new file mode 100644 index 0000000..3e940b8 --- /dev/null +++ b/vendor/editline/examples/Makefile.am @@ -0,0 +1,5 @@ +noinst_PROGRAMS = testit cli excallback fileman +LDADD = $(top_builddir)/src/libeditline.la +AM_CPPFLAGS = -DEDITLINE_LIBRARY +AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include +AM_LDFLAGS = -static diff --git a/vendor/editline/examples/cli.c b/vendor/editline/examples/cli.c new file mode 100644 index 0000000..368d04a --- /dev/null +++ b/vendor/editline/examples/cli.c @@ -0,0 +1,168 @@ +/* Custom CLI command completion. + * + * Copyright (c) 1992, 1993 Simmule Turner and Rich Salz. All rights reserved. + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or of the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * 1. The authors are not responsible for the consequences of use of this + * software, no matter how awful, even if they arise from flaws in it. + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Since few users ever read sources, + * credits must appear in the documentation. + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. Since few users + * ever read sources, credits must appear in the documentation. + * 4. This notice may not be removed or altered. + */ + +#include "editline.h" +#include + +#define HISTORY "/tmp/.cli-history" + +static char *list[] = { + "foo ", "bar ", "bsd ", "cli ", "ls ", "cd ", "malloc ", "tee ", NULL +}; + +/* Attempt to complete the pathname, returning an allocated copy. + * Fill in *unique if we completed it, or set it to 0 if ambiguous. */ +static char *my_rl_complete(char *token, int *match) +{ + int i; + int index = -1; + int matchlen = 0; + int count = 0; + + for (i = 0; list[i]; i++) { + int partlen = strlen (token); /* Part of token */ + + if (!strncmp (list[i], token, partlen)) { + index = i; + matchlen = partlen; + count ++; + } + } + + if (count == 1) { + *match = 1; + return strdup (list[index] + matchlen); + } + + return NULL; +} + +/* Return all possible completions. */ +static int my_rl_list_possib(char *token, char ***av) +{ + int i, num, total = 0; + char **copy; + + for (num = 0; list[num]; num++) + ; + + copy = (char **) malloc (num * sizeof(char *)); + for (i = 0; i < num; i++) { + if (!strncmp (list[i], token, strlen (token))) { + copy[total] = strdup (list[i]); + total ++; + } + } + *av = copy; + + return total; +} + +el_status_t list_possible(void) +{ + char **av; + char *word; + int ac; + + word = el_find_word(); + ac = rl_list_possib(word, &av); + if (word) + free(word); + if (ac) { + el_print_columns(ac, av); + while (--ac >= 0) + free(av[ac]); + free(av); + + return CSmove; + } + + return el_ring_bell(); +} + +el_status_t do_suspend(void) +{ + puts("Abort!"); + return CSstay; +} + +static void breakit(int signo) +{ + puts("Got SIGINT"); +} + +int main(void) +{ + char *line; + char *prompt = "cli> "; + char *passwd = "Enter password: "; + + signal(SIGINT, breakit); + + /* Setup callbacks */ + rl_set_complete_func(&my_rl_complete); + rl_set_list_possib_func(&my_rl_list_possib); + + el_bind_key('?', list_possible); + el_bind_key(CTL('Z'), do_suspend); + read_history(HISTORY); + + while ((line = readline(prompt))) { + int next = 0; + + /* Use el_no_echo when reading passwords and similar */ + if (!strncmp(line, "unlock", 6)) { + el_no_echo = 1; + while ((line = readline(passwd))) { + if (strncmp(line, "secret", 6)) { + printf("\nWrong password, please try again, it's secret.\n"); + free(line); + continue; + } + + el_no_echo = 0; + + printf("\nAchievement unlocked!\n"); + free(line); + next = 1; + break; + } + } + + if (next) + continue; + + if (*line != '\0') + printf("\t\t\t|%s|\n", line); + free(line); + } + + write_history(HISTORY); + + return 0; +} + +/** + * Local Variables: + * c-file-style: "k&r" + * c-basic-offset: 4 + * End: + */ diff --git a/vendor/editline/examples/excallback.c b/vendor/editline/examples/excallback.c new file mode 100644 index 0000000..015132a --- /dev/null +++ b/vendor/editline/examples/excallback.c @@ -0,0 +1,195 @@ +/* +From: Jeff Solomon +Date: Fri, 9 Apr 1999 10:13:27 -0700 (PDT) +To: chet@po.cwru.edu +Subject: new readline example +Message-ID: <14094.12094.527305.199695@mrclean.Stanford.EDU> + +Chet, + +I've been using readline 4.0. Specifically, I've been using the perl +version Term::ReadLine::Gnu. It works great. + +Anyway, I've been playing around the alternate interface and I wanted +to contribute a little C program, callback.c, to you that you could +use as an example of the alternate interface in the /examples +directory of the readline distribution. + +My example shows how, using the alternate interface, you can +interactively change the prompt (which is very nice imo). Also, I +point out that you must roll your own terminal setting when using the +alternate interface because readline depreps (using your parlance) the +terminal while in the user callback. I try to demostrate what I mean +with an example. I've included the program below. + +To compile, I just put the program in the examples directory and made +the appropriate changes to the EXECUTABLES and OBJECTS line and added +an additional target 'callback'. + +I compiled on my Sun Solaris2.6 box using Sun's cc. + +Let me know what you think. + +Jeff +*/ + +#if defined (HAVE_CONFIG_H) +#include +#endif + +#include +#include + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include /* xxx - should make this more general */ + +#ifdef EDITLINE_LIBRARY +# include "editline.h" +#else +# include +#endif + +/* This little examples demonstrates the alternate interface to using readline. + * In the alternate interface, the user maintains control over program flow and + * only calls readline when STDIN is readable. Using the alternate interface, + * you can do anything else while still using readline (like talking to a + * network or another program) without blocking. + * + * Specifically, this program highlights two importants features of the + * alternate interface. The first is the ability to interactively change the + * prompt, which can't be done using the regular interface since rl_prompt is + * read-only. + * + * The second feature really highlights a subtle point when using the alternate + * interface. That is, readline will not alter the terminal when inside your + * callback handler. So let's so, your callback executes a user command that + * takes a non-trivial amount of time to complete (seconds). While your + * executing the command, the user continues to type keystrokes and expects them + * to be re-echoed on the new prompt when it returns. Unfortunately, the default + * terminal configuration doesn't do this. After the prompt returns, the user + * must hit one additional keystroke and then will see all of his previous + * keystrokes. To illustrate this, compile and run this program. Type "sleep" at + * the prompt and then type "bar" before the prompt returns (you have 3 + * seconds). Notice how "bar" is re-echoed on the prompt after the prompt + * returns? This is what you expect to happen. Now comment out the 4 lines below + * the line that says COMMENT LINE BELOW. Recompile and rerun the program and do + * the same thing. When the prompt returns, you should not see "bar". Now type + * "f", see how "barf" magically appears? This behavior is un-expected and not + * desired. + */ + +void process_line(char *line); +int change_prompt(void); +char *get_prompt(void); + +int prompt = 1; +char prompt_buf[40], line_buf[256]; +tcflag_t old_lflag; +cc_t old_vtime; +struct termios term; + +int +main() +{ + fd_set fds; + + /* Adjust the terminal slightly before the handler is installed. Disable + * canonical mode processing and set the input character time flag to be + * non-blocking. + */ + if( tcgetattr(STDIN_FILENO, &term) < 0 ) { + perror("tcgetattr"); + exit(1); + } + old_lflag = term.c_lflag; + old_vtime = term.c_cc[VTIME]; + term.c_lflag &= ~ICANON; + term.c_cc[VTIME] = 1; + /* COMMENT LINE BELOW - see above */ + if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) { + perror("tcsetattr"); + exit(1); + } + +// rl_add_defun("change-prompt", change_prompt, CTRL('t')); + rl_callback_handler_install(get_prompt(), process_line); + + while(1) { + FD_ZERO(&fds); + FD_SET(fileno(stdin), &fds); + + if( select(FD_SETSIZE, &fds, NULL, NULL, NULL) < 0) { + perror("select"); + exit(1); + } + + if( FD_ISSET(fileno(stdin), &fds) ) { + rl_callback_read_char(); + } + } + + return 0; +} + +void +process_line(char *line) +{ + if( line == NULL ) { + fprintf(stderr, "\n"); + + /* reset the old terminal setting before exiting */ + term.c_lflag = old_lflag; + term.c_cc[VTIME] = old_vtime; + if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) { + perror("tcsetattr"); + exit(1); + } + exit(0); + } + + if( strcmp(line, "sleep") == 0 ) { + sleep(3); + } else { + fprintf(stderr, "|%s|\n", line); + } + + free (line); +} + +int +change_prompt(void) +{ + /* toggle the prompt variable */ + prompt = !prompt; + + /* save away the current contents of the line */ + strncpy(line_buf, rl_line_buffer, sizeof(line_buf)); + line_buf[sizeof(line_buf) - 1] = 0; + + /* install a new handler which will change the prompt and erase the current line */ + rl_callback_handler_install(get_prompt(), process_line); + + /* insert the old text on the new line */ + rl_insert_text(line_buf); + + /* redraw the current line - this is an undocumented function. It invokes the + * redraw-current-line command. + */ + return rl_refresh_line(0, 0); +} + +char * +get_prompt(void) +{ + /* The prompts can even be different lengths! */ + sprintf(prompt_buf, "%s", + prompt ? "Hit ctrl-t to toggle prompt> " : "Pretty cool huh?> "); + return prompt_buf; +} diff --git a/vendor/editline/examples/fileman.c b/vendor/editline/examples/fileman.c new file mode 100644 index 0000000..088fec8 --- /dev/null +++ b/vendor/editline/examples/fileman.c @@ -0,0 +1,431 @@ +/* fileman.c -- A tiny application which demonstrates how to use the + GNU Readline library. This application interactively allows users + to manipulate files and their modes. + + NOTE: this was taken from the GNU Readline documentation and ported + to libedit. A command to output the history list was added. + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "editline.h" + +void too_dangerous(char *caller); +void initialize_readline(); +int execute_line(char *line); +int valid_argument(char *caller, char *arg); + +/* The names of functions that actually do the manipulation. */ +int com_list(char *); +int com_view(char *); +int com_history(char *); +int com_rename(char *); +int com_stat(char *); +int com_pwd(char *); +int com_delete(char *); +int com_help(char *); +int com_cd(char *); +int com_quit(char *); + +struct cmd { + char *name; /* User printable name of the function. */ + int (*func)(char *); /* Function to call to do the job. */ + char *doc; /* Documentation for this function. */ +}; + +struct cmd commands[] = { + { "cd", com_cd, "Change to directory DIR"}, + { "delete", com_delete, "Delete FILE"}, + { "help", com_help, "Display this text"}, + { "?", com_help, "Synonym for `help'"}, + { "list", com_list, "List files in DIR"}, + { "ls", com_list, "Synonym for `list'"}, + { "pwd", com_pwd, "Print the current working directory"}, + { "quit", com_quit, "Quit using Fileman"}, + { "rename", com_rename, "Rename FILE to NEWNAME"}, + { "stat", com_stat, "Print out statistics on FILE"}, + { "view", com_view, "View the contents of FILE"}, + { "history", com_history, "List editline history"}, + { NULL, NULL, NULL }, +}; + +/* Forward declarations. */ +char *stripwhite(); +struct cmd *find_command(); + +/* When non-zero, this means the user is done using this program. */ +int done; + +int main(int argc, char **argv) +{ + char *line, *s; + + setlocale(LC_CTYPE, ""); + + initialize_readline(); /* Bind our completer. */ + + /* Loop reading and executing lines until the user quits. */ + for (; done == 0;) { + line = readline("FileMan: "); + + if (!line) + break; + + /* Remove leading and trailing whitespace from the line. + Then, if there is anything left, add it to the history list + and execute it. */ + s = stripwhite(line); +#if 0 + if (*s) { + + char *expansion; + int result; + + result = history_expand(s, &expansion); + if (result < 0 || result == 2) { + fprintf(stderr, "%s\n", expansion); + } else { + add_history(expansion); + execute_line(expansion); + } + free(expansion); + } +#else + execute_line(s); +#endif + free(line); + } + + return 0; +} + +/* Execute a command line. */ +int execute_line(char *line) +{ + int i; + struct cmd *command; + char *word; + + /* Isolate the command word. */ + i = 0; + while (line[i] && isspace(line[i])) + i++; + word = line + i; + + while (line[i] && !isspace(line[i])) + i++; + + if (line[i]) + line[i++] = '\0'; + + command = find_command(word); + + if (!command) { + fprintf(stderr, "%s: No such command for FileMan.\n", word); + return -1; + } + + /* Get argument to command, if any. */ + while (isspace(line[i])) + i++; + + word = line + i; + + /* Call the function. */ + return command->func(word); +} + +/* Look up NAME as the name of a command, and return a pointer to that + command. Return a NULL pointer if NAME isn't a command name. */ +struct cmd *find_command(char *name) +{ + int i; + + for (i = 0; commands[i].name; i++) + if (strcmp(name, commands[i].name) == 0) + return &commands[i]; + + return NULL; +} + +/* + * Strip whitespace from the start and end of STRING. Return a pointer + * into STRING. + */ +char *stripwhite(char *string) +{ + char *s, *t; + + for (s = string; isspace(*s); s++) ; + + if (*s == 0) + return s; + + t = s + strlen(s) - 1; + while (t > s && isspace(*t)) + t--; + *++t = '\0'; + + return s; +} + +/* **************************************************************** */ +/* */ +/* Interface to Readline Completion */ +/* */ +/* **************************************************************** */ + +char *command_generator(const char *, int); +char **fileman_completion(const char *, int, int); + +/* + * Tell the GNU Readline library how to complete. We want to try to + * complete on command names if this is the first word in the line, or + * on filenames if not. + */ +void initialize_readline(void) +{ + /* Allow conditional parsing of the ~/.inputrc file. */ + rl_readline_name = "FileMan"; + + /* Tell the completer that we want a crack first. */ + rl_attempted_completion_function = fileman_completion; +} + +/* + * Attempt to complete on the contents of TEXT. START and END + * bound the region of rl_line_buffer that contains the word to + * complete. TEXT is the word to complete. We can use the entire + * contents of rl_line_buffer in case we want to do some simple + * parsing. Returnthe array of matches, or NULL if there aren't any. + */ +char **fileman_completion(const char *text, int start, int end) +{ + char **matches = NULL; + + /* If this word is at the start of the line, then it is a command + to complete. Otherwise it is the name of a file in the current + directory. */ + if (start == 0) + matches = rl_completion_matches(text, command_generator); + + return matches; +} + +/* Generator function for command completion. STATE lets us + know whether to start from scratch; without any state + (i.e. STATE == 0), then we start at the top of the list. */ +char *command_generator(const char *text, int state) +{ + static int list_index, len; + char *name; + + /* If this is a new word to complete, initialize now. This + includes saving the length of TEXT for efficiency, and + initializing the index variable to 0. */ + if (!state) { + list_index = 0; + len = strlen(text); + } + + /* Return the next name which partially matches from the + command list. */ + while ((name = commands[list_index].name)) { + list_index++; + + if (strncmp(name, text, len) == 0) + return strdup(name); + } + + /* If no names matched, then return NULL. */ + return NULL; +} + +/* **************************************************************** */ +/* */ +/* FileMan Commands */ +/* */ +/* **************************************************************** */ + +/* String to pass to system (). This is for the LIST, VIEW and RENAME + commands. */ +static char syscom[1024]; + +/* List the file(s) named in arg. */ +int com_list(char *arg) +{ + if (!arg) + arg = ""; + + sprintf(syscom, "ls -FClg %s", arg); + + return system(syscom); +} + +int com_view(char *arg) +{ + if (!valid_argument("view", arg)) + return 1; + + sprintf(syscom, "more %s", arg); + + return system(syscom); +} + +int com_history(char *arg) +{ + const char *he; + + /* rewind history */ + while (el_prev_hist()) ; + + for (he = el_next_hist(); he != NULL; he = el_next_hist()) + printf("%s\n", he); + + return 0; +} + +int com_rename(char *arg) +{ + too_dangerous("rename"); + return 1; +} + +int com_stat(char *arg) +{ + struct stat finfo; + + if (!valid_argument("stat", arg)) + return 1; + + if (stat(arg, &finfo) == -1) { + perror(arg); + return 1; + } + + printf("Statistics for `%s':\n", arg); + + printf("%s has %ld link%s, and is %lld byte%s in length.\n", arg, + (long)finfo.st_nlink, + (finfo.st_nlink == 1) ? "" : "s", + (long long)finfo.st_size, (finfo.st_size == 1) ? "" : "s"); + printf("Inode Last Change at: %s", ctime(&finfo.st_ctime)); + printf(" Last access at: %s", ctime(&finfo.st_atime)); + printf(" Last modified at: %s", ctime(&finfo.st_mtime)); + + return 0; +} + +int com_delete(char *arg) +{ + too_dangerous("delete"); + return 1; +} + +/* Print out help for ARG, or for all of the commands if ARG is + not present. */ +int com_help(char *arg) +{ + int i; + int printed = 0; + + for (i = 0; commands[i].name; i++) { + if (!*arg || (strcmp(arg, commands[i].name) == 0)) { + printf("%s\t\t%s.\n", commands[i].name, + commands[i].doc); + printed++; + } + } + + if (!printed) { + printf("No commands match `%s'. Possibilties are:\n", arg); + + for (i = 0; commands[i].name; i++) { + /* Print in six columns. */ + if (printed == 6) { + printed = 0; + printf("\n"); + } + + printf("%s\t", commands[i].name); + printed++; + } + + if (printed) + printf("\n"); + } + + return 0; +} + +/* Change to the directory ARG. */ +int com_cd(char *arg) +{ + if (chdir(arg) == -1) { + perror(arg); + return 1; + } + + com_pwd(""); + return 0; +} + +/* Print out the current working directory. */ +int com_pwd(char *ignore) +{ + char dir[1024], *s; + + s = getcwd(dir, sizeof(dir) - 1); + if (!s) { + printf("Error getting pwd: %s\n", dir); + return 1; + } + + printf("Current directory is %s\n", dir); + return 0; +} + +/* The user wishes to quit using this program. Just set DONE + non-zero. */ +int com_quit(char *arg) +{ + done = 1; + return 0; +} + +/* Function which tells you that you can't do this. */ +void too_dangerous(char *caller) +{ + fprintf(stderr, "%s: Too dangerous for me to distribute.\n", caller); + fprintf(stderr, "Write it yourself.\n"); +} + +/* Return non-zero if ARG is a valid argument for CALLER, + else print an error message and return zero. */ +int valid_argument(char *caller, char *arg) +{ + if (!arg || !*arg) { + fprintf(stderr, "%s: Argument required.\n", caller); + return 0; + } + + return 1; +} + +/** + * Local Variables: + * c-file-style: "k&r" + * c-basic-offset: 4 + * End: + */ diff --git a/vendor/editline/examples/testit.c b/vendor/editline/examples/testit.c new file mode 100644 index 0000000..204dc76 --- /dev/null +++ b/vendor/editline/examples/testit.c @@ -0,0 +1,78 @@ +/* A "micro-shell" to test editline library. + * If given any arguments, commands aren't executed. + * + * Copyright (c) 1992, 1993 Simmule Turner and Rich Salz. All rights reserved. + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or of the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * 1. The authors are not responsible for the consequences of use of this + * software, no matter how awful, even if they arise from flaws in it. + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Since few users ever read sources, + * credits must appear in the documentation. + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. Since few users + * ever read sources, credits must appear in the documentation. + * 4. This notice may not be removed or altered. + */ +#include +#include +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#include "editline.h" + +#ifndef HAVE_PERROR +extern int errno; +void perror(char *s) +{ + fprintf(stderr, "%s: error %d\n", s, errno); +} +#endif /* !HAVE_PERROR */ + +int main(int argc, char *argv[] __attribute__ ((unused))) +{ + int doit; + char *prompt, *p; + + read_history(".testit_history"); + + doit = argc == 1; + if ((prompt = getenv("TESTPROMPT")) == NULL) + prompt = "testit> "; + + while ((p = readline(prompt)) != NULL) { + printf("\t\t\t|%s|\n", p); + if (doit) { + if (strncmp(p, "cd ", 3) == 0) { + if (chdir(&p[3]) < 0) + perror(&p[3]); + } else if (system(p) != 0) { + perror(p); + } + } + free(p); + } + + write_history(".testit_history"); + rl_uninitialize(); + + return 0; +} + +/** + * Local Variables: + * c-file-style: "k&r" + * c-basic-offset: 4 + * End: + */ diff --git a/vendor/editline/include/Makefile.am b/vendor/editline/include/Makefile.am new file mode 100644 index 0000000..17bdc7e --- /dev/null +++ b/vendor/editline/include/Makefile.am @@ -0,0 +1,2 @@ +library_includedir = $(includedir) +library_include_HEADERS = editline.h diff --git a/vendor/editline/include/editline.h b/vendor/editline/include/editline.h new file mode 100644 index 0000000..7ae8810 --- /dev/null +++ b/vendor/editline/include/editline.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 1992, 1993 Simmule Turner and Rich Salz + * All rights reserved. + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or of the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * 1. The authors are not responsible for the consequences of use of this + * software, no matter how awful, even if they arise from flaws in it. + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Since few users ever read sources, + * credits must appear in the documentation. + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. Since few users + * ever read sources, credits must appear in the documentation. + * 4. This notice may not be removed or altered. + */ +#ifndef EDITLINE_H_ +#define EDITLINE_H_ + +/* Handy macros when binding keys. */ +#define CTL(x) ((x) & 0x1F) +#define ISCTL(x) ((x) && (x) < ' ') +#define UNCTL(x) ((x) + 64) +#define META(x) ((x) | 0x80) +#define ISMETA(x) ((x) & 0x80) +#define UNMETA(x) ((x) & 0x7F) + +#ifdef __cplusplus +extern "C" { +#endif + +/* Command status codes. */ +typedef enum { + CSdone = 0, /* OK */ + CSeof, /* Error, or EOF */ + CSmove, + CSdispatch, + CSstay, + CSsignal +} el_status_t; + +/* Editline specific types, despite rl_ prefix. From Heimdal project. */ +typedef int rl_list_possib_func_t(char*, char***); +typedef el_status_t el_keymap_func_t(void); +typedef int rl_hook_func_t(void); +typedef int rl_getc_func_t(void); +typedef void rl_voidfunc_t(void); +typedef void rl_vintfunc_t(int); +typedef void rl_vcpfunc_t(char *); + +/* FSF Readline compat tupes */ +typedef char *rl_complete_func_t (char *, int*); +typedef char *rl_compentry_func_t (const char *, int); +typedef char **rl_completion_func_t (const char *, int, int); + +/* Display 8-bit chars "as-is" or as `M-x'? Toggle with M-m. (Default:0 - "as-is") */ +extern int rl_meta_chars; + +/* Editline specific functions. */ +extern char * el_find_word(void); +extern void el_print_columns(int ac, char **av); +extern el_status_t el_ring_bell(void); +extern el_status_t el_del_char(void); + +extern el_status_t el_bind_key(int key, el_keymap_func_t function); +extern el_status_t el_bind_key_in_metamap(int key, el_keymap_func_t function); + +extern const char *el_next_hist(void); +extern const char *el_prev_hist(void); + +extern char *rl_complete(char *token, int *match); +extern int rl_list_possib(char *token, char ***av); +extern char **rl_completion_matches(const char *token, rl_compentry_func_t *generator); +extern char *rl_filename_completion_function(const char *text, int state); + +/* For compatibility with FSF readline. */ +extern int rl_point; +extern int rl_mark; +extern int rl_end; +extern int rl_inhibit_complete; +extern char *rl_line_buffer; +extern const char *rl_readline_name; +extern FILE *rl_instream; /* The stdio stream from which input is read. Defaults to stdin if NULL - Not supported yet! */ +extern FILE *rl_outstream; /* The stdio stream to which output is flushed. Defaults to stdout if NULL - Not supported yet! */ +extern int el_no_echo; /* E.g under emacs, don't echo except prompt */ +extern int el_no_hist; /* Disable auto-save of and access to history -- e.g. for password prompts or wizards */ +extern int el_hist_size; /* size of history scrollback buffer, default: 15 */ + +extern void rl_initialize (void); +extern void rl_reset_terminal (const char *terminal_name); +extern void rl_uninitialize (void); + +extern void rl_save_prompt (void); +extern void rl_restore_prompt (void); +extern void rl_set_prompt (const char *prompt); + +extern void rl_clear_message (void); +extern void rl_forced_update_display(void); + +extern void rl_prep_terminal (int meta_flag); +extern void rl_deprep_terminal (void); + +extern int rl_getc(void); +extern int rl_insert_text (const char *text); +extern int rl_refresh_line (int ignore1, int ignore2); + +extern char *readline (const char *prompt); + +extern void add_history (const char *line); +extern int read_history (const char *filename); +extern int write_history (const char *filename); + +extern rl_getc_func_t *rl_set_getc_func(rl_getc_func_t *func); + +extern rl_completion_func_t *rl_attempted_completion_function; +extern rl_complete_func_t *rl_set_complete_func (rl_complete_func_t *func); +extern rl_list_possib_func_t *rl_set_list_possib_func (rl_list_possib_func_t *func); + +/* Alternate interface to plain readline(), for event loops */ +extern void rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *lhandler); +extern void rl_callback_read_char (void); +extern void rl_callback_handler_remove (void); + +#ifdef __cplusplus +} +#endif + +#endif /* EDITLINE_H_ */ diff --git a/vendor/editline/libeditline.pc.in b/vendor/editline/libeditline.pc.in new file mode 100644 index 0000000..eb5e735 --- /dev/null +++ b/vendor/editline/libeditline.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: @PACKAGE@ +Description: A small line editing library without termcap/curses +Version: @VERSION@ +Requires: +Libs: -L${libdir} -leditline +Cflags: -I${includedir} + diff --git a/vendor/editline/m4/.gitignore b/vendor/editline/m4/.gitignore new file mode 100644 index 0000000..0f4126c --- /dev/null +++ b/vendor/editline/m4/.gitignore @@ -0,0 +1 @@ +*.m4 diff --git a/vendor/editline/man/Makefile.am b/vendor/editline/man/Makefile.am new file mode 100644 index 0000000..de973bf --- /dev/null +++ b/vendor/editline/man/Makefile.am @@ -0,0 +1,3 @@ +AUTOMAKE_OPTIONS = foreign + +dist_man_MANS = editline.3 diff --git a/vendor/editline/man/editline.3 b/vendor/editline/man/editline.3 new file mode 100644 index 0000000..daf8a1c --- /dev/null +++ b/vendor/editline/man/editline.3 @@ -0,0 +1,274 @@ +.Dd April 27, 2019 +.Dt EDITLINE 3 +.Os +.Sh NAME +.Nm editline +.Nd command-line editing library with history +.Sh LIBRARY +.Lb libeditline +.Sh SYNOPSIS +.In editline.h +.Fn "char *readline" "const char *prompt" +.Fn "void add_history" "const char *line" +.Fn "int read_history" "const char *filename" +.Fn "int write_history" "const char *filename" +.Sh DESCRIPTION +.Nm +is a library that provides n line-editing interface with history. It +is intended to be functionally equivalent with the +.Nm readline +library provided by the Free Software Foundation, but much smaller. The +bulk of this manual page describes the basic user interface. More APIs, +both native and for +.Nm readline +compatibility , +are also available. See the +.Cm editline.h +header file for details. +.Pp +The +.Fn readline +function displays the given +.Fa prompt +on stdout, waits for user input on stdin and then returns a line of text +with the trailing newline removed. The data is returned in a buffer +allocated with +.Xr malloc 3 , +so the space should be released with +.Xr free 3 +when the calling program is done with it. +.Pp +Each line returned is automatically saved in the internal history list, +unless it happens to be equal to the previous line. This is +configurable if you are building editline from source, i.e. if you would +rather like to call +.Fn add_history +manually. +.Pp +The +.Fn read_history +and +.Fn write_history +functions can be used to load and store the history of your application. +.Em Note: +these APIs do not do any tilde or environment variable expansion of the +given filename. +.Ss User Interface +A program that uses this library provides a simple emacs-like editing +interface to its users. A line may be edited before it is sent to the +calling program by typing either control characters or escape sequences. +A control character, shown as a caret followed by a letter, is typed by +holding down the control key while the letter is typed. For example, +.Cm ^A +is a control-A. An escape sequence is entered by typing the escape key +followed by one or more characters. The escape key is abbreviated as +.Cm ESC . +Note that unlike control keys, case matters in escape sequences; +.Cm ESC F +is not the same as +.Cm ESC f . +.Pp +An editing command may be typed anywhere on the line, not just at the +beginning. In addition, a return may also be typed anywhere on the +line, not just at the end. +.Pp +Most editing commands may be given a repeat count, +.Ar n , +where +.Ar n +is a number. To enter a repeat count, type the escape key, the number, +and then the command to execute. For example, +.Cm ESC 4 ^f +moves forward four characters. If a command may be given a repeat count +then the text +.Cm [n] +is given at the end of its description. +.Pp +The following control characters are accepted: +.Pp +.Bl -tag -width "ESC DEL " -compact +.It ^A +Move to the beginning of the line +.It ^B +Move left (backwards) [n] +.It ^D +Delete character [n] +.It ^E +Move to end of line +.It ^F +Move right (forwards) [n] +.It ^G +Ring the bell +.It ^H +Delete character before cursor (backspace key) [n] +.It ^I +Complete filename (tab key); see below +.It ^J +Done with line (return key) +.It ^K +Kill to end of line (or column [n]) +.It ^L +Redisplay line +.It ^M +Done with line (alternate return key) +.It ^N +Get next line from history [n] +.It ^P +Get previous line from history [n] +.It ^R +Search backward (forward if [n]) through history for text; prefixing the +string with a caret (^) forces it to match only at the beginning of a +history line +.It ^T +Transpose characters +.It ^V +Insert next character, even if it is an edit command +.It ^W +Wipe to the mark +.It ^X^X +Exchange current location and mark +.It ^Y +Yank back last killed text +.It ^[ +Start an escape sequence (escape key) +.It ^]c +Move forward to next character +.Cm c +.It ^? +Delete character before cursor (delete key) [n] +.El +.Pp +The following escape sequences are provided: +.Pp +.Bl -tag -width "ESC DEL " -compact +.It ESC ^H +Delete previous word (backspace key) [n] +.It ESC DEL +Delete previous word (delete key) [n] +.It ESC SP +Set the mark (space key); see ^X^X and ^Y above +.It ESC\ . +Get the last (or [n]'th) word from previous line +.It ESC\ ? +Show possible completions; see below +.It ESC < +Move to start of history +.It ESC > +Move to end of history +.It ESC b +Move backward a word [n] +.It ESC d +Delete word under cursor [n] +.It ESC f +Move forward a word [n] +.It ESC l +Make word lowercase [n] +.It ESC m +Toggle if 8bit chars display normally or with an +.Ar M- +prefix +.It ESC u +Make word uppercase [n] +.It ESC y +Yank back last killed text +.It ESC v +Show library version +.It ESC w +Make area up to mark yankable +.It ESC nn +Set repeat count to the number nn +.It ESC C +Read from environment variable +.Ar $C , +where +.Ar C +is an uppercase letter +.El +.Pp +The +.Nm +library has a small macro facility. If you type the escape key followed +by an uppercase letter, +.Ar C , +then the contents of the environment variable +.Ar $C +are read in as if you had typed them at the keyboard. For example, if +the variable +.Ar $L +contains the following: +.Pp +.Dl ^A^Kecho '^V^[[H^V^[[2J'^M +.Pp +Then typing +.Cm ESC L +will move to the beginning of the line, kill the entire line, enter the +echo command needed to clear the terminal (if your terminal is like a +VT-100), and send the line back to the shell. +.Pp +The +.Nm +library also does filename completion. Suppose the root directory has +the following files in it: +.Pp +.Dl bin vmunix +.Dl core vmunix.old +.Pp +If you type +.Cm rm /v +and then the tab key, +.Nm +will then finish off as much of the name as possible by adding +.Ar munix . +Because the name is not unique, it will then beep. If you type the +escape key and a question mark, it will display the two choices. If you +then type a period and a tab, the library will finish off the filename +for you: +.Pp +.Bd -ragged -offset indent +rm /v[TAB] +.Em munix +\&.[TAB] +.Em old +.Ed +.Pp +The tab key is shown by [TAB] and the automatically-entered text +is shown in italics, or underline. +.Sh USAGE +To include +.Nm +in your program, call it as you do any other function and link your +program with +.Ar -leditline . +.Ss Example +The following brief example lets you enter a line and edit it, then displays it. +.Pp +.Bd -literal -offset indent +#include +#include +#include + +int main(void) +{ + char *p; + + while ((p = readline("CLI> "))) { + puts(p); + free(p); + } + + return 0; +} +.El +.Sh AUTHORS +The original editline library was posted to comp.sources.unix newsgroup +by created by Simmule R. Turner and Rich Salz in 1992. It now exists in +several forks: Debian, Minix, Heimdal, Festival speech tools, Mozilla, +Google Gadgets for Linux, and many other places. The original manual +page was made by David W. Sanderson. +.Pp +This version was originally based on the Minix 2 sources, but has since +evolved to include patches from all relevant forks. It is currently +maintained by Joachim Nilsson at GitHub, +.Aq http://github.com/troglobit/editline +.Sh BUGS +Does not handle multiple lines or unicode characters well. diff --git a/vendor/editline/src/.gitignore b/vendor/editline/src/.gitignore new file mode 100644 index 0000000..3057f3a --- /dev/null +++ b/vendor/editline/src/.gitignore @@ -0,0 +1,2 @@ +libeditline.a +libeditline.la diff --git a/vendor/editline/src/Makefile.am b/vendor/editline/src/Makefile.am new file mode 100644 index 0000000..702893a --- /dev/null +++ b/vendor/editline/src/Makefile.am @@ -0,0 +1,6 @@ +lib_LTLIBRARIES = libeditline.la +libeditline_la_SOURCES = editline.c editline.h complete.c sysunix.c unix.h +libeditline_la_CFLAGS = -std=gnu99 +libeditline_la_CFLAGS += -W -Wall -Wextra -Wundef -Wunused -Wstrict-prototypes +libeditline_la_CFLAGS += -Werror-implicit-function-declaration -Wshadow -Wcast-qual +libeditline_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0 diff --git a/vendor/editline/src/complete.c b/vendor/editline/src/complete.c new file mode 100644 index 0000000..d6b8a4b --- /dev/null +++ b/vendor/editline/src/complete.c @@ -0,0 +1,442 @@ +/* History and file completion functions for editline library. + * + * Copyright (c) 1992, 1993 Simmule Turner and Rich Salz + * All rights reserved. + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or of the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * 1. The authors are not responsible for the consequences of use of this + * software, no matter how awful, even if they arise from flaws in it. + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Since few users ever read sources, + * credits must appear in the documentation. + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. Since few users + * ever read sources, credits must appear in the documentation. + * 4. This notice may not be removed or altered. + */ + +#include +#include "editline.h" + +#define MAX_TOTAL_MATCHES (256 << sizeof(char *)) + +int rl_attempted_completion_over = 0; +rl_completion_func_t *rl_attempted_completion_function = NULL; +rl_compentry_func_t *rl_completion_entry_function = NULL; + +/* Wrap strcmp() for qsort() -- weird construct to pass -Wcast-qual */ +static int compare(const void *p1, const void *p2) +{ + char *const *v1 = (char *const *)p1; + char *const *v2 = (char *const *)p2; + + return strcmp(*v1, *v2); +} + +/* Fill in *avp with an array of names that match file, up to its length. + * Ignore . and .. . */ +static int FindMatches(char *dir, char *file, char ***avp) +{ + char **av; + char **word; + char *p; + DIR *dp; + DIRENTRY *ep; + size_t ac; + size_t len; + size_t choices; + size_t total; + + if ((dp = opendir(dir)) == NULL) + return 0; + + av = NULL; + ac = 0; + len = strlen(file); + choices = 0; + total = 0; + while ((ep = readdir(dp)) != NULL) { + p = ep->d_name; + if (p[0] == '.' && (p[1] == '\0' || (p[1] == '.' && p[2] == '\0'))) + continue; + if (len && strncmp(p, file, len) != 0) + continue; + + choices++; + if ((total += strlen(p)) > MAX_TOTAL_MATCHES) { + /* This is a bit too much. */ + while (ac > 0) free(av[--ac]); + continue; + } + + if ((ac % MEM_INC) == 0) { + word = malloc(sizeof(char *) * (ac + MEM_INC)); + if (!word) { + total = 0; + break; + } + + if (ac) { + memcpy(word, av, ac * sizeof(char *)); + free(av); + } + *avp = av = word; + } + + if ((av[ac] = strdup(p)) == NULL) { + if (ac == 0) + free(av); + total = 0; + break; + } + ac++; + } + + /* Clean up and return. */ + closedir(dp); + if (total > MAX_TOTAL_MATCHES) { + char many[sizeof(total) * 3]; + + p = many + sizeof(many); + *--p = '\0'; + while (choices > 0) { + *--p = '0' + choices % 10; + choices /= 10; + } + + while (p > many + sizeof(many) - 8) + *--p = ' '; + + if ((p = strdup(p)) != NULL) + av[ac++] = p; + + if ((p = strdup("choices")) != NULL) + av[ac++] = p; + } else { + if (ac) + qsort(av, ac, sizeof(char *), compare); + } + + return ac; +} + +/* Split a pathname into allocated directory and trailing filename parts. */ +static int SplitPath(const char *path, char **dirpart, char **filepart) +{ + static char DOT[] = "."; + char *dpart; + char *fpart; + + if ((fpart = strrchr(path, '/')) == NULL) { + if ((dpart = strdup(DOT)) == NULL) + return -1; + + if ((fpart = strdup(path)) == NULL) { + free(dpart); + return -1; + } + } else { + if ((dpart = strdup(path)) == NULL) + return -1; + + dpart[fpart - path + 1] = '\0'; + if ((fpart = strdup(fpart + 1)) == NULL) { + free(dpart); + return -1; + } + } + *dirpart = dpart; + *filepart = fpart; + + return 0; +} + +static rl_complete_func_t *el_complete_func = NULL; + +/* For compatibility with the Heimdal project. */ +rl_complete_func_t *rl_set_complete_func(rl_complete_func_t *func) +{ + rl_complete_func_t *old = el_complete_func; + el_complete_func = func; + + return old; +} + +/* Attempt to complete the pathname, returning an allocated copy. + * Fill in *match if we completed it, or set it to 0 if ambiguous. */ +char *el_filename_complete(char *pathname, int *match) +{ + char **av; + char *dir; + char *file; + char *path; + char *p; + size_t ac; + size_t end; + size_t i; + size_t j; + size_t len; + + if (SplitPath((const char *)pathname, &dir, &file) < 0) + return NULL; + + if ((ac = FindMatches(dir, file, &av)) == 0) { + free(dir); + free(file); + + return NULL; + } + + p = NULL; + len = strlen(file); + if (ac == 1) { + /* Exactly one match -- finish it off. */ + *match = 1; + j = strlen(av[0]) - len + 2; + p = malloc(sizeof(char) * (j + 1)); + if (p) { + memcpy(p, av[0] + len, j); + len = strlen(dir) + strlen(av[0]) + 2; + path = malloc(sizeof(char) * len); + if (path) { + snprintf(path, len, "%s/%s", dir, av[0]); + rl_add_slash(path, p); + free(path); + } + } + } else { + *match = 0; + if (len) { + /* Find largest matching substring. */ + for (i = len, end = strlen(av[0]); i < end; i++) { + for (j = 1; j < ac; j++) { + if (av[0][i] != av[j][i]) + goto breakout; + } + } + breakout: + if (i > len) { + j = i - len + 1; + p = malloc(sizeof(char) * j); + if (p) { + memcpy(p, av[0] + len, j); + p[j - 1] = '\0'; + } + } + } + } + + /* Clean up and return. */ + free(dir); + free(file); + for (i = 0; i < ac; i++) + free(av[i]); + free(av); + + return p; +} + +char *rl_filename_completion_function(const char *text, int state) +{ + char *dir; + char *file; + static char **av; + static size_t i, ac; + + if (!state) { + if (SplitPath(text, &dir, &file) < 0) + return NULL; + + ac = FindMatches(dir, file, &av); + free(dir); + free(file); + if (!ac) + return NULL; + + i = 0; + } + + if (i < ac) + return av[i++]; + + do { + free(av[--i]); + } while (i > 0); + + return NULL; +} + +/* Similar to el_find_word(), but used by GNU Readline API */ +static char *rl_find_token(size_t *len) +{ + char *ptr; + int pos; + + for (pos = rl_point; pos < rl_end; pos++) { + if (isspace(rl_line_buffer[pos])) { + if (pos > 0) + pos--; + break; + } + } + + ptr = &rl_line_buffer[pos]; + while (pos >= 0 && !isspace(rl_line_buffer[pos])) { + if (pos == 0) + break; + + pos--; + } + + if (ptr != &rl_line_buffer[pos]) { + *len = (size_t)(ptr - &rl_line_buffer[pos]); + return &rl_line_buffer[pos]; + } + + return NULL; +} + +/* + * "uses an application-supplied generator function to generate the list + * of possible matches, and then returns the array of these matches. The + * caller should place the address of its generator function in + * rl_completion_entry_function" + */ +char **rl_completion_matches(const char *token, rl_compentry_func_t *generator) +{ + int state = 0, num = 0; + char **array, *entry; + + if (!generator) { + generator = rl_completion_entry_function; + if (!generator) + generator = rl_filename_completion_function; + } + + if (!generator) + return NULL; + + array = malloc(512 * sizeof(char *)); + if (!array) + return NULL; + + while (num < 511 && (entry = generator(token, state))) { + state = 1; + array[num++] = entry; + } + array[num] = NULL; + + if (!num) { + free(array); + return NULL; + } + + return array; +} + +static char *complete(char *token, int *match) +{ + size_t len = 0; + char *word, **words = NULL; + int start, end; + + word = rl_find_token(&len); + if (!word) + goto fallback; + + start = word - rl_line_buffer; + end = start + len; + + word = strndup(word, len); + if (!word) + goto fallback; + + rl_attempted_completion_over = 0; + words = rl_attempted_completion_function(word, start, end); + + if (!rl_attempted_completion_over && !words) + words = rl_completion_matches(word, NULL); + + if (words) { + int i = 0; + + free(word); + word = NULL; + if (words[0]) + word = strdup(words[0] + len); + + while (words[i]) + free(words[i++]); + free(words); + + if (word) + return word; + } + +fallback: + return el_filename_complete(token, match); +} + +/* + * First check for editline specific custom completion function, then + * for any GNU Readline compat, then fallback to filename completion. + */ +char *rl_complete(char *token, int *match) +{ + if (el_complete_func) + return el_complete_func(token, match); + + if (rl_attempted_completion_function) + return complete(token, match); + + return el_filename_complete(token, match); +} + +static rl_list_possib_func_t *el_list_possib_func = NULL; + +/* For compatibility with the Heimdal project. */ +rl_list_possib_func_t *rl_set_list_possib_func(rl_list_possib_func_t *func) +{ + rl_list_possib_func_t *old = el_list_possib_func; + el_list_possib_func = func; + return old; +} + +/* Default possible completions. */ +int el_filename_list_possib(char *pathname, char ***av) +{ + char *dir; + char *file; + int ac; + + if (SplitPath(pathname, &dir, &file) < 0) + return 0; + + ac = FindMatches(dir, file, av); + free(dir); + free(file); + + return ac; +} + +/* Return all possible completions. */ +int rl_list_possib(char *token, char ***av) +{ + if (el_list_possib_func) + return el_list_possib_func(token, av); + + return el_filename_list_possib(token, av); +} + + +/** + * Local Variables: + * c-file-style: "k&r" + * c-basic-offset: 4 + * End: + */ diff --git a/vendor/editline/src/editline.c b/vendor/editline/src/editline.c new file mode 100644 index 0000000..86e05a0 --- /dev/null +++ b/vendor/editline/src/editline.c @@ -0,0 +1,1969 @@ +/* + * Copyright (c) 1992, 1993 Simmule Turner and Rich Salz + * All rights reserved. + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or of the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * 1. The authors are not responsible for the consequences of use of this + * software, no matter how awful, even if they arise from flaws in it. + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Since few users ever read sources, + * credits must appear in the documentation. + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. Since few users + * ever read sources, credits must appear in the documentation. + * 4. This notice may not be removed or altered. + */ + +#include +#include +#include +#include + +#include "editline.h" + +/* +** Manifest constants. +*/ +#define SCREEN_COLS 80 +#define SCREEN_ROWS 24 +#define EL_STDIN 0 +#define EL_STDOUT 1 +#define NO_ARG (-1) +#define DEL 127 +#define SEPS "\"#$&'()*:;<=>?[\\]^`{|}~\n\t " + +/* +** The type of case-changing to perform. +*/ +typedef enum { + TOupper, TOlower, TOcapitalize +} el_case_t; + +/* +** Key to command mapping. +*/ +typedef struct { + int Key; + el_status_t (*Function)(void); +} el_keymap_t; + +/* +** Command history structure. +*/ +typedef struct { + int Size; + int Pos; + char **Lines; +} el_hist_t; + +/* User definable callbacks. */ +rl_getc_func_t *rl_getc_function = rl_getc; +rl_hook_func_t *rl_event_hook; +rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal; +rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal; + +/* +** Globals. +*/ +int rl_eof; +int rl_erase; +int rl_intr; +int rl_kill; +int rl_quit; +#ifdef CONFIG_SIGSTOP +int rl_susp; +#endif + +int el_hist_size = 15; +static el_hist_t H = { + .Size = 0, + .Pos = 0, + .Lines = NULL, +}; + +static char NILSTR[] = ""; +static const char *el_input = NILSTR; +static char *Yanked; +static char *Screen; +static char NEWLINE[]= CRLF; +static char CLEAR[]= "\ec"; +static const char *el_term = "dumb"; +static int Repeat; +static int old_point; +static int el_push_back; +static int el_pushed; +static int el_intr_pending; +static int el_infd = EL_STDIN; +static int el_outfd = EL_STDOUT; +static el_keymap_t Map[]; +static el_keymap_t MetaMap[]; +static size_t Length = 0; +static size_t ScreenCount; +static size_t ScreenSize; +static char *backspace = "\b"; +static char *old_search = NULL; +static int tty_cols = SCREEN_COLS; +static int tty_rows = SCREEN_ROWS; +static int Searching = 0; +static const char *(*search_move)(void); +static const char *old_prompt = NULL; +static rl_vcpfunc_t *line_handler = NULL; + +int el_no_echo = 0; /* e.g., under Emacs */ +int el_no_hist = 0; +int rl_point; +int rl_mark; +int rl_end; +int rl_meta_chars = 0; /* Display 8-bit chars as the actual char(0) or as `M-x'(1)? */ +int rl_inhibit_complete = 0; +char *rl_line_buffer = NULL; +const char *rl_prompt = NULL; +const char *rl_readline_name = NULL; /* Set by calling program, for conditional parsing of ~/.inputrc - Not supported yet! */ +FILE *rl_instream = NULL; /* The stdio stream from which input is read. Defaults to stdin if NULL */ +FILE *rl_outstream = NULL; /* The stdio stream to which output is flushed. Defaults to stdout if NULL */ + +/* Declarations. */ +static char *editinput(int complete); +#ifdef CONFIG_USE_TERMCAP +extern char *tgetstr(const char *, char **); +extern int tgetent(char *, const char *); +extern int tgetnum(const char *); +#endif + + +/* +** Misc. local helper functions. +*/ +static int is_alpha_num(unsigned char c) +{ + if (isalnum(c)) + return 1; + if (ISMETA(c)) + return 1; + if (ISCTL(c)) + return 1; + + return 0; +} + +/* +** TTY input/output functions. +*/ + +static void tty_flush(void) +{ + ssize_t res; + + if (!ScreenCount) + return; + + if (!el_no_echo) { + res = write(el_outfd, Screen, ScreenCount); + if (res > 0) + ScreenCount = 0; + } +} + +static void tty_put(const char c) +{ + if (el_no_echo) + return; + + Screen[ScreenCount] = c; + if (++ScreenCount >= ScreenSize) { + ScreenSize += SCREEN_INC; + Screen = realloc(Screen, sizeof(char) * ScreenSize); + } +} + +static void tty_puts(const char *p) +{ + while (*p) + tty_put(*p++); +} + +static void tty_show(unsigned char c) +{ + if (c == DEL) { + tty_put('^'); + tty_put('?'); + } else if (ISCTL(c)) { + tty_put('^'); + tty_put(UNCTL(c)); + } else if (rl_meta_chars && ISMETA(c)) { + tty_put('M'); + tty_put('-'); + tty_put(UNMETA(c)); + } else { + tty_put(c); + } +} + +static void tty_string(char *p) +{ + while (*p) + tty_show(*p++); +} + +static void tty_push(int c) +{ + el_pushed = 1; + el_push_back = c; +} + +int rl_getc(void) +{ + int r; + char c; + + do { + r = read(el_infd, &c, 1); + } while (r == -1 && errno == EINTR); + + return r == 1 ? c : EOF; +} + +static int tty_get(void) +{ + tty_flush(); + + if (el_pushed) { + el_pushed = 0; + return el_push_back; + } + + if (*el_input) + return *el_input++; + + return rl_getc_function(); +} + +#define tty_back() tty_puts(backspace) + +static void tty_backn(int n) +{ + while (--n >= 0) + tty_back(); +} + +static void tty_info(void) +{ + rl_reset_terminal(NULL); +} + + +/* +** Glue routines to rl_ttyset() +*/ +void rl_prep_terminal(int meta_flag) +{ + rl_meta_chars = !meta_flag; + rl_ttyset(0); +} + +void rl_deprep_terminal(void) +{ + rl_ttyset(1); +} + +/* +** Print an array of words in columns. +*/ +void el_print_columns(int ac, char **av) +{ + char *p; + int i; + int j; + int k; + int len; + int skip; + int longest; + int cols; + int colwidth; + + /* Find longest name, determine column count from that. */ + for (longest = 0, i = 0; i < ac; i++) { + if ((j = strlen((char *)av[i])) > longest) + longest = j; + } + colwidth = longest + 3; + if (colwidth > tty_cols) colwidth = tty_cols; + cols = tty_cols / colwidth; + + tty_puts(NEWLINE); + for (skip = ac / cols + 1, i = 0; i < skip; i++) { + for (j = i; j < ac; j += skip) { + for (p = av[j], len = strlen((char *)p), k = len; --k >= 0; p++) + tty_put(*p); + + if (j + skip < ac) { + while (++len < colwidth) + tty_put(' '); + } + } + + tty_puts(NEWLINE); + } +} + +static void reposition(void) +{ + int i; + + tty_put('\r'); + tty_puts(rl_prompt); + for (i = 0; i < rl_point; i++) + tty_show(rl_line_buffer[i]); +} + +static void left(el_status_t Change) +{ + if (rl_point) { + tty_back(); + if (ISMETA(rl_line_buffer[rl_point - 1])) { + if (rl_meta_chars) { + tty_back(); + tty_back(); + } + } else if (ISCTL(rl_line_buffer[rl_point - 1])) { + tty_back(); + } + } + + if (Change == CSmove) + rl_point--; +} + +static void right(el_status_t Change) +{ + tty_show(rl_line_buffer[rl_point]); + + if (Change == CSmove) + rl_point++; +} + +el_status_t el_ring_bell(void) +{ + tty_put('\07'); + tty_flush(); + + return CSstay; +} + +static el_status_t do_macro(int c) +{ + char name[4]; + + name[0] = '_'; + name[1] = c; + name[2] = '_'; + name[3] = '\0'; + + if ((el_input = (char *)getenv((char *)name)) == NULL) { + el_input = NILSTR; + return el_ring_bell(); + } + + return CSstay; +} + +/* Skip forward to start of next word. If @move is set we also move the cursor. */ +static el_status_t do_forward(el_status_t move) +{ + int i; + char *p; + + i = 0; + do { + p = &rl_line_buffer[rl_point]; + + /* Skip leading whitespace, like FSF Readline */ + for ( ; rl_point < rl_end && (p[0] == ' ' || !is_alpha_num(p[0])); rl_point++, p++) { + if (move == CSmove) + right(CSstay); + } + + /* Skip to end of word, if inside a word. */ + for (; rl_point < rl_end && is_alpha_num(p[0]); rl_point++, p++) { + if (move == CSmove) + right(CSstay); + } + + /* Skip to next word, or skip leading white space if outside a word. */ + for ( ; rl_point < rl_end && (p[0] == ' ' || !is_alpha_num(p[0])); rl_point++, p++) { + if (move == CSmove) + right(CSstay); + } + + if (rl_point == rl_end) + break; + } while (++i < Repeat); + + return CSstay; +} + +static el_status_t do_case(el_case_t type) +{ + int i; + int end; + int count; + char *p; + + do_forward(CSstay); + if (old_point != rl_point) { + if ((count = rl_point - old_point) < 0) + count = -count; + + rl_point = old_point; + if ((end = rl_point + count) > rl_end) + end = rl_end; + + for (i = rl_point, p = &rl_line_buffer[i]; rl_point < end; p++) { + if ((type == TOupper) || (type == TOcapitalize && rl_point == i)) { + if (islower(*p)) + *p = toupper(*p); + } else if (isupper(*p)) { + *p = tolower(*p); + } + right(CSmove); + } + } + + return CSstay; +} + +static el_status_t case_down_word(void) +{ + return do_case(TOlower); +} + +static el_status_t case_up_word(void) +{ + return do_case(TOupper); +} + +static el_status_t case_cap_word(void) +{ + return do_case(TOcapitalize); +} + +static void ceol(void) +{ + int extras = 0; + int i; + char *p; + + while (rl_point < 0) { + tty_put(' '); + rl_point++; + extras++; + } + + for (i = rl_point, p = &rl_line_buffer[i]; i <= rl_end; i++, p++) { + tty_put(' '); + if (ISMETA(*p)) { + if (rl_meta_chars) { + tty_put(' '); + tty_put(' '); + extras += 2; + } + } else if (ISCTL(*p)) { + tty_put(' '); + extras++; + } + } + + for (i += extras; i > rl_point; i--) + tty_back(); +} + +static void clear_line(void) +{ + rl_point = -(int)strlen(rl_prompt); + tty_put('\r'); + ceol(); + rl_point = 0; + rl_end = 0; + rl_line_buffer[0] = '\0'; +} + +static el_status_t insert_string(const char *p) +{ + size_t len; + int i; + char *line; + char *q; + + len = strlen(p); + if (rl_end + len >= Length) { + line = malloc(sizeof(char) * (Length + len + MEM_INC)); + if (!line) + return CSstay; + + if (Length) { + memcpy(line, rl_line_buffer, Length); + free(rl_line_buffer); + } + + rl_line_buffer = line; + Length += len + MEM_INC; + } + + for (q = &rl_line_buffer[rl_point], i = rl_end - rl_point; --i >= 0; ) + q[len + i] = q[i]; + + memcpy(&rl_line_buffer[rl_point], p, len); + rl_end += len; + rl_line_buffer[rl_end] = '\0'; + tty_string(&rl_line_buffer[rl_point]); + rl_point += len; + + return rl_point == rl_end ? CSstay : CSmove; +} + +int rl_insert_text(const char *text) +{ + int mark = rl_point; + + insert_string(text); + ceol(); + + return rl_point - mark; +} + +static el_status_t redisplay(int cls) +{ + if (cls && rl_point == 0 && rl_end == 0) + tty_puts(CLEAR); + else + tty_puts("\r\e[K"); + + tty_puts(rl_prompt); + tty_string(rl_line_buffer); + + return CSmove; +} + +static el_status_t refresh(void) +{ + return redisplay(1); +} + +int rl_refresh_line(int ignore1 __attribute__((unused)), int ignore2 __attribute__((unused))) +{ + redisplay(0); + return 0; +} + +static el_status_t toggle_meta_mode(void) +{ + rl_meta_chars = ! rl_meta_chars; + return redisplay(0); +} + + +const char *el_next_hist(void) +{ + return H.Pos >= H.Size - 1 ? NULL : H.Lines[++H.Pos]; +} + +const char *el_prev_hist(void) +{ + return H.Pos == 0 ? NULL : H.Lines[--H.Pos]; +} + +static el_status_t do_insert_hist(const char *p) +{ + if (p == NULL) + return el_ring_bell(); + + clear_line(); + + rl_point = 0; + reposition(); + rl_end = 0; + + return insert_string(p); +} + +static el_status_t do_hist(const char *(*move)(void)) +{ + const char *p; + int i = 0; + + do { + if ((p = move()) == NULL) + return el_ring_bell(); + } while (++i < Repeat); + + return do_insert_hist(p); +} + +static el_status_t h_next(void) +{ + if (el_no_hist) + return CSstay; + + return do_hist(el_next_hist); +} + +static el_status_t h_prev(void) +{ + if (el_no_hist) + return CSstay; + + return do_hist(el_prev_hist); +} + +static el_status_t h_first(void) +{ + return do_insert_hist(H.Lines[H.Pos = 0]); +} + +static el_status_t h_last(void) +{ + return do_insert_hist(H.Lines[H.Pos = H.Size - 1]); +} + +/* +** Return zero if pat appears as a substring in text. +*/ +static int substrcmp(const char *text, const char *pat, size_t len) +{ + char c; + + if ((c = *pat) == '\0') + return *text == '\0'; + + for ( ; *text; text++) { + if (*text == c && strncmp(text, pat, len) == 0) + return 0; + } + + return 1; +} + +static const char *search_hist(const char *search, const char *(*move)(void)) +{ + int len; + int pos; + int (*match)(const char *s1, const char *s2, size_t n); + const char *pat; + + /* Save or get remembered search pattern. */ + if (search && *search) { + if (old_search) + free(old_search); + old_search = strdup(search); + } else { + if (old_search == NULL || *old_search == '\0') + return NULL; + search = old_search; + } + + /* Set up pattern-finder. */ + if (*search == '^') { + match = strncmp; + pat = search + 1; + } else { + match = substrcmp; + pat = search; + } + len = strlen(pat); + + pos = H.Pos; /* Save H.Pos */ + while (move()) { + if (match(H.Lines[H.Pos], pat, len) == 0) + return H.Lines[H.Pos]; + } + H.Pos = pos; /* Restore H.Pos */ + + return NULL; +} + +static el_status_t h_search_end(const char *p) +{ + rl_prompt = old_prompt; + Searching = 0; + + if (el_intr_pending > 0) { + el_intr_pending = 0; + clear_line(); + return redisplay(0); + } + + p = search_hist(p, search_move); + if (p == NULL) { + el_ring_bell(); + clear_line(); + return redisplay(0); + } + + return do_insert_hist(p); +} + +static el_status_t h_search(void) +{ + if (Searching) + return el_ring_bell(); + Searching = 1; + + clear_line(); + old_prompt = rl_prompt; + rl_prompt = "Search: "; + tty_puts(rl_prompt); + + search_move = Repeat == NO_ARG ? el_prev_hist : el_next_hist; + if (line_handler) { + editinput(0); + return CSstay; + } + + return h_search_end(editinput(1)); +} + +static el_status_t fd_char(void) +{ + int i = 0; + + do { + if (rl_point >= rl_end) + break; + right(CSmove); + } while (++i < Repeat); + return CSstay; +} + +static void save_yank(int begin, int i) +{ + if (Yanked) { + free(Yanked); + Yanked = NULL; + } + + if (i < 1) + return; + + Yanked = malloc(sizeof(char) * (i + 1)); + if (Yanked) { + memcpy(Yanked, &rl_line_buffer[begin], i); + Yanked[i] = '\0'; + } +} + +static el_status_t delete_string(int count) +{ + int i; + char *p; + + if (count <= 0 || rl_end == rl_point) + return el_ring_bell(); + + if (count == 1 && rl_point == rl_end - 1) { + /* Optimize common case of delete at end of line. */ + rl_end--; + p = &rl_line_buffer[rl_point]; + i = 1; + tty_put(' '); + if (ISCTL(*p)) { + i = 2; + tty_put(' '); + } else if (rl_meta_chars && ISMETA(*p)) { + i = 3; + tty_put(' '); + tty_put(' '); + } + tty_backn(i); + *p = '\0'; + return CSmove; + } + + if (rl_point + count > rl_end && (count = rl_end - rl_point) <= 0) + return CSstay; + + if (count > 1) + save_yank(rl_point, count); + + for (p = &rl_line_buffer[rl_point], i = rl_end - (rl_point + count) + 1; --i >= 0; p++) + p[0] = p[count]; + ceol(); + rl_end -= count; + tty_string(&rl_line_buffer[rl_point]); + + return CSmove; +} + +static el_status_t bk_char(void) +{ + int i = 0; + + do { + if (rl_point == 0) + break; + left(CSmove); + } while (++i < Repeat); + + return CSstay; +} + +static el_status_t bk_del_char(void) +{ + int i = 0; + + do { + if (rl_point == 0) + break; + left(CSmove); + } while (++i < Repeat); + + return delete_string(i); +} + +static el_status_t kill_line(void) +{ + int i; + + if (Repeat != NO_ARG) { + if (Repeat < rl_point) { + i = rl_point; + rl_point = Repeat; + reposition(); + delete_string(i - rl_point); + } else if (Repeat > rl_point) { + right(CSmove); + delete_string(Repeat - rl_point - 1); + } + + return CSmove; + } + + save_yank(rl_point, rl_end - rl_point); + rl_line_buffer[rl_point] = '\0'; + ceol(); + rl_end = rl_point; + + return CSstay; +} + +static el_status_t insert_char(int c) +{ + el_status_t s; + char buff[2]; + char *p; + char *q; + int i; + + if (Repeat == NO_ARG || Repeat < 2) { + buff[0] = c; + buff[1] = '\0'; + + return insert_string(buff); + } + + p = malloc(sizeof(char) * (Repeat + 1)); + if (!p) + return CSstay; + + for (i = Repeat, q = p; --i >= 0; ) + *q++ = c; + *q = '\0'; + Repeat = 0; + s = insert_string(p); + free(p); + + return s; +} + +static el_status_t beg_line(void) +{ + if (rl_point) { + rl_point = 0; + return CSmove; + } + + return CSstay; +} + +static el_status_t end_line(void) +{ + if (rl_point != rl_end) { + rl_point = rl_end; + return CSmove; + } + + return CSstay; +} + +static el_status_t del_char(void) +{ + return delete_string(Repeat == NO_ARG ? CSeof : Repeat); +} + +el_status_t el_del_char(void) +{ + return del_char(); +} + +static el_status_t fd_word(void) +{ + return do_forward(CSmove); +} + +static el_status_t bk_word(void) +{ + int i; + char *p; + + i = 0; + do { + for (p = &rl_line_buffer[rl_point]; p > rl_line_buffer && !is_alpha_num(p[-1]); p--) + left(CSmove); + + for (; p > rl_line_buffer && !isblank(p[-1]) && is_alpha_num(p[-1]); p--) + left(CSmove); + + if (rl_point == 0) + break; + } while (++i < Repeat); + + return CSstay; +} + +static el_status_t meta(void) +{ + int c; + el_keymap_t *kp; + + if ((c = tty_get()) == EOF) + return CSeof; + +#ifdef CONFIG_ANSI_ARROWS + /* Also include VT-100 arrows. */ + if (c == '[' || c == 'O') { + switch (tty_get()) { + case EOF: return CSeof; + case '1': + { + char seq[4] = { 0 }; + + for (c = 0; c < 3; c++) + seq[c] = tty_get(); + + if (!strncmp(seq, ";5C", 3)) + return fd_word(); /* Ctrl+Right */ + if (!strncmp(seq, ";5D", 3)) + return bk_word(); /* Ctrl+Left */ + + break; + } + case '2': tty_get(); return CSstay; /* Insert */ + case '3': tty_get(); return del_char(); /* Delete */ + case '5': tty_get(); return CSstay; /* PgUp */ + case '6': tty_get(); return CSstay; /* PgDn */ + case 'A': return h_prev(); /* Up */ + case 'B': return h_next(); /* Down */ + case 'C': return fd_char(); /* Left */ + case 'D': return bk_char(); /* Right */ + case 'F': return end_line(); /* End */ + case 'H': return beg_line(); /* Home */ + default: /* Fall through */ + break; + } + + return el_ring_bell(); + } +#endif /* CONFIG_ANSI_ARROWS */ + + if (isdigit(c)) { + for (Repeat = c - '0'; (c = tty_get()) != EOF && isdigit(c); ) + Repeat = Repeat * 10 + c - '0'; + tty_push(c); + + return CSstay; + } + + if (isupper(c)) + return do_macro(c); + + for (kp = MetaMap; kp->Function; kp++) { + if (kp->Key == c) + return kp->Function(); + } + + return el_ring_bell(); +} + +static el_status_t emacs(int c) +{ + el_status_t s; + el_keymap_t *kp; + + /* Save point before interpreting input character 'c'. */ + old_point = rl_point; + + if (rl_meta_chars && ISMETA(c)) { + tty_push(UNMETA(c)); + return meta(); + } + + for (kp = Map; kp->Function; kp++) { + if (kp->Key == c) + break; + } + + if (kp->Function) { + s = kp->Function(); + if (s == CSdispatch) /* If Function is inhibited. */ + s = insert_char(c); + } else { + s = insert_char(c); + } + + if (!el_pushed) { + /* No pushback means no repeat count; hacky, but true. */ + Repeat = NO_ARG; + } + + return s; +} + +static el_status_t tty_special(int c) +{ +#ifdef CONFIG_SIGINT + if (c == rl_intr) { + el_intr_pending = SIGINT; + return CSsignal; + } +#endif + if (c == rl_quit) { + el_intr_pending = SIGQUIT; + return CSeof; + } +#ifdef CONFIG_SIGSTOP + if (c == rl_susp) { + el_intr_pending = SIGTSTP; + return CSsignal; + } +#endif + + if (rl_meta_chars && ISMETA(c)) + return CSdispatch; + + if (c == rl_erase || c == DEL) + return bk_del_char(); + + if (c == rl_kill) { + if (rl_point != 0) { + rl_point = 0; + reposition(); + } + Repeat = NO_ARG; + + return kill_line(); + } + +#ifdef CONFIG_EOF + if (c == rl_eof && rl_point == 0 && rl_end == 0) + return CSeof; +#endif + + return CSdispatch; +} + +static char *editinput(int complete) +{ + int c; + + do { + c = tty_get(); + if (c == EOF) + break; + + switch (tty_special(c)) { + case CSdone: + return rl_line_buffer; + + case CSeof: + return NULL; + + case CSsignal: + return (char *)""; + + case CSmove: + reposition(); + break; + + case CSdispatch: + switch (emacs(c)) { + case CSdone: + return rl_line_buffer; + + case CSeof: + return NULL; + + case CSsignal: + return (char *)""; + + case CSmove: + reposition(); + break; + + case CSdispatch: + case CSstay: + break; + } + break; + + case CSstay: + break; + } + } while (complete); + + return NULL; +} + +static void hist_alloc(void) +{ + if (!H.Lines) + H.Lines = calloc(el_hist_size, sizeof(char *)); +} + +static void hist_add(const char *p) +{ + int i; + char *s; + +#ifdef CONFIG_UNIQUE_HISTORY + if (H.Size && strcmp(p, H.Lines[H.Size - 1]) == 0) + return; +#endif + + s = strdup(p); + if (s == NULL) + return; + + if (H.Size < el_hist_size) { + H.Lines[H.Size++] = s; + } else { + free(H.Lines[0]); + for (i = 0; i < el_hist_size - 1; i++) + H.Lines[i] = H.Lines[i + 1]; + H.Lines[i] = s; + } + H.Pos = H.Size - 1; +} + +static char *read_redirected(void) +{ + int size = MEM_INC; + char *p; + char *line; + char *end; + + p = line = malloc(sizeof(char) * size); + if (!p) + return NULL; + + end = p + size; + while (1) { + if (p == end) { + int oldpos = end - line; + + size += MEM_INC; + p = line = realloc(line, sizeof(char) * size); + if (!p) + return NULL; + end = p + size; + + p += oldpos; /* Continue where we left off... */ + } + + if (read(el_infd, p, 1) <= 0) { + /* Ignore "incomplete" lines at EOF, just like we do for a tty. */ + free(line); + return NULL; + } + + if (*p == '\n') + break; + p++; + } + *p = '\0'; + + return line; +} + +/* For compatibility with FSF readline. */ +void rl_reset_terminal(const char *terminal_name) +{ +#ifdef CONFIG_USE_TERMCAP + char buf[1024]; + char *bp; +#endif +#ifdef TIOCGWINSZ + struct winsize W; +#endif + + if (terminal_name) { + el_term = terminal_name; + } else if ((el_term = getenv("TERM")) == NULL) { + el_term = "dumb"; + } + + /* Initialize to faulty values to trigger fallback if nothing else works. */ + tty_cols = tty_rows = -1; + +#ifdef CONFIG_USE_TERMCAP + bp = buf; + if (-1 != tgetent(buf, el_term)) { + if ((backspace = tgetstr("le", &bp)) != NULL) + backspace = strdup(backspace); + tty_cols = tgetnum("co"); + tty_rows = tgetnum("li"); + } + /* Make sure to check width & rows and fallback to TIOCGWINSZ if available. */ +#endif + + if (tty_cols <= 0 || tty_rows <= 0) { +#ifdef TIOCGWINSZ + if (ioctl(el_outfd, TIOCGWINSZ, &W) >= 0 && W.ws_col > 0 && W.ws_row > 0) { + tty_cols = (int)W.ws_col; + tty_rows = (int)W.ws_row; + return; + } +#endif + tty_cols = SCREEN_COLS; + tty_rows = SCREEN_ROWS; + } +} + +void rl_initialize(void) +{ + if (!rl_prompt) + rl_prompt = "? "; + + hist_alloc(); + + /* Setup I/O descriptors */ + if (!rl_instream) el_infd = EL_STDIN; + else el_infd = fileno(rl_instream); + if (el_infd < 0) el_infd = EL_STDIN; + if (!rl_outstream) el_outfd = EL_STDOUT; + else el_outfd = fileno(rl_outstream); + if (el_outfd < 0) el_outfd = EL_STDOUT; +} + +void rl_uninitialize(void) +{ + int i; + + /* Uninitialize the history */ + if (H.Lines) { + for (i = 0; i < el_hist_size; i++) { + if (H.Lines[i]) + free(H.Lines[i]); + H.Lines[i] = NULL; + } + free(H.Lines); + H.Lines = NULL; + } + H.Size = 0; + H.Pos = 0; + + if (old_search) + free(old_search); + old_search = NULL; + + /* Uninitialize the line buffer */ + if (rl_line_buffer) + free(rl_line_buffer); + rl_line_buffer = NULL; + Length = 0; +} + +static const char *rl_saved_prompt = NULL; +void rl_save_prompt(void) +{ + rl_saved_prompt = rl_prompt; +} + +void rl_restore_prompt(void) +{ + if (rl_saved_prompt) + rl_prompt = rl_saved_prompt; +} + +void rl_set_prompt(const char *prompt) +{ + rl_prompt = prompt; +} + +void rl_clear_message(void) +{ + /* Nothing to do atm. */ +} + +void rl_forced_update_display() +{ + redisplay(0); + tty_flush(); +} + +static int el_prep(const char *prompt) +{ + rl_initialize(); + + if (!rl_line_buffer) { + Length = MEM_INC; + rl_line_buffer = malloc(sizeof(char) * Length); + if (!rl_line_buffer) + return -1; + } + + tty_info(); + rl_prep_term_function(!rl_meta_chars); + hist_add(NILSTR); + ScreenSize = SCREEN_INC; + Screen = malloc(sizeof(char) * ScreenSize); + if (!Screen) + return -1; + + rl_prompt = prompt ? prompt : NILSTR; + if (el_no_echo) { + int old = el_no_echo; + + el_no_echo = 0; + tty_puts(rl_prompt); + tty_flush(); + el_no_echo = old; + } else { + tty_puts(rl_prompt); + } + + Repeat = NO_ARG; + old_point = rl_point = rl_mark = rl_end = 0; + rl_line_buffer[0] = '\0'; + el_intr_pending = -1; + + return 0; +} + +static char *el_deprep(char *line) +{ + if (line) { + line = strdup(line); + tty_puts(NEWLINE); + tty_flush(); + } + + rl_deprep_term_function(); + if (Screen) { + free(Screen); + Screen = NULL; + } + + free(H.Lines[--H.Size]); + H.Lines[H.Size] = NULL; + + /* Add to history, unless no-echo or no-history mode ... */ + if (!el_no_echo && !el_no_hist) { + if (line != NULL && *line != '\0') + hist_add(line); + } + + if (el_intr_pending > 0) { + int signo = el_intr_pending; + + el_intr_pending = 0; + kill(getpid(), signo); + } + + return line; +} + +void rl_callback_handler_install(const char *prompt, rl_vcpfunc_t *lhandler) +{ + if (!lhandler) + return; + line_handler = lhandler; + + /* + * Any error from el_prep() is handled by the lhandler callbck as + * soon as the user calls rl_callback_read_char(). + */ + el_prep(prompt); + tty_flush(); +} + +/* + * Reads one character at a time, when a complete line has been received + * the lhandler from rl_callback_handler_install() is called with the + * line as argument. + * + * If the callback returns the terminal is prepped for reading a new + * line. + * + * If any error occurs, either in the _install() phase, or while reading + * one character, this function restores the terminal and calls lhandler + * with a NULL argument. + */ +void rl_callback_read_char(void) +{ + char *line; + + if (!line_handler) { + errno = EINVAL; + return; + } + + /* + * Check if rl_callback_handler_install() failed + * This is the only point where we can tell user + */ + if (!Screen || !rl_line_buffer) { + errno = ENOMEM; + line_handler(el_deprep(NULL)); + return; + } + + line = editinput(0); + if (line) { + char *l; + + if (Searching) { + h_search_end(line); + tty_flush(); + return; + } + + l = el_deprep(line); + line_handler(l); + + if (el_prep(rl_prompt)) + line_handler(NULL); + } + tty_flush(); +} + +void rl_callback_handler_remove(void) +{ + if (!line_handler) + return; + + el_deprep(NULL); + line_handler = NULL; +} + +char *readline(const char *prompt) +{ + /* Unless called by the user already. */ + rl_initialize(); + + if (!isatty(el_infd)) { + tty_flush(); + + return read_redirected(); + } + + if (el_prep(prompt)) + return NULL; + + return el_deprep(editinput(1)); +} + +/* + * Even though readline() itself adds history automatically, the user + * can also add lines. This is for compatibility with GNU Readline. + */ +void add_history(const char *p) +{ + if (p == NULL || *p == '\0') + return; + + hist_add(p); +} + + +int read_history(const char *filename) +{ + FILE *fp; + char buf[SCREEN_INC]; + + hist_alloc(); + fp = fopen(filename, "r"); + if (fp) { + H.Size = 0; + while (H.Size < el_hist_size) { + if (!fgets(buf, SCREEN_INC, fp)) + break; + + buf[strlen(buf) - 1] = 0; /* Remove '\n' */ + add_history(buf); + } + + return fclose(fp); + } + + return errno; +} + +int write_history(const char *filename) +{ + FILE *fp; + + hist_alloc(); + fp = fopen(filename, "w"); + if (fp) { + int i = 0; + + while (i < H.Size) + fprintf(fp, "%s\n", H.Lines[i++]); + + return fclose(fp); + } + + return errno; +} + + +/* +** Move back to the beginning of the current word and return an +** allocated copy of it. +*/ +char *el_find_word(void) +{ + char *p, *q; + char *word; + size_t len; + + p = &rl_line_buffer[rl_point]; + while (p > rl_line_buffer) { + p--; + if (p > rl_line_buffer && p[-1] == '\\') { + p--; + } else { + if (strchr(SEPS, (char) *p) != NULL) { + p++; + break; + } + } + } + + len = rl_point - (p - rl_line_buffer) + 1; + word = malloc(sizeof(char) * len); + if (!word) + return NULL; + + q = word; + while (p < &rl_line_buffer[rl_point]) { + if (*p == '\\') { + if (++p == &rl_line_buffer[rl_point]) + break; + } + *q++ = *p++; + } + *q = '\0'; + + return word; +} + +static el_status_t c_possible(void) +{ + char **av; + char *word; + int ac; + + word = el_find_word(); + ac = rl_list_possib(word, &av); + if (word) + free(word); + if (ac) { + el_print_columns(ac, av); + while (--ac >= 0) + free(av[ac]); + free(av); + + return CSmove; + } + + return el_ring_bell(); +} + +static el_status_t c_complete(void) +{ + char *p, *q; + char *word, *string; + size_t len; + int unique; + el_status_t s = CSdone; + + if (rl_inhibit_complete) + return CSdispatch; + + word = el_find_word(); + p = rl_complete(word, &unique); + if (word) + free(word); + if (p) { + len = strlen(p); + word = p; + + string = q = malloc(sizeof(char) * (2 * len + 1)); + if (!string) { + free(word); + return CSstay; + } + + while (*p) { + if ((*p < ' ' || strchr(SEPS, *p) != NULL) + && (!unique || p[1] != 0)) { + *q++ = '\\'; + } + *q++ = *p++; + } + *q = '\0'; + free(word); + + if (len > 0) { + s = insert_string(string); +#ifdef CONFIG_TERMINAL_BELL + if (!unique) + el_ring_bell(); +#endif + } + free(string); + + if (len > 0) + return s; + } + + return c_possible(); +} + +static el_status_t accept_line(void) +{ + rl_line_buffer[rl_end] = '\0'; + return CSdone; +} + +#ifdef SYSTEM_IS_WIN32 +static el_status_t end_of_input(void) +{ + rl_line_buffer[rl_end] = '\0'; + return CSeof; +} +#endif + +static el_status_t transpose(void) +{ + char c; + + if (rl_point) { + if (rl_point == rl_end) + left(CSmove); + c = rl_line_buffer[rl_point - 1]; + left(CSstay); + rl_line_buffer[rl_point - 1] = rl_line_buffer[rl_point]; + tty_show(rl_line_buffer[rl_point - 1]); + rl_line_buffer[rl_point++] = c; + tty_show(c); + } + + return CSstay; +} + +static el_status_t quote(void) +{ + int c; + + return (c = tty_get()) == EOF ? CSeof : insert_char((int)c); +} + +static el_status_t mk_set(void) +{ + rl_mark = rl_point; + return CSstay; +} + +static el_status_t exchange(void) +{ + int c; + + if ((c = tty_get()) != CTL('X')) + return c == EOF ? CSeof : el_ring_bell(); + + if ((c = rl_mark) <= rl_end) { + rl_mark = rl_point; + rl_point = c; + return CSmove; + } + + return CSstay; +} + +static el_status_t yank(void) +{ + if (Yanked && *Yanked) + return insert_string(Yanked); + + return CSstay; +} + +static el_status_t copy_region(void) +{ + if (rl_mark > rl_end) + return el_ring_bell(); + + if (rl_point > rl_mark) + save_yank(rl_mark, rl_point - rl_mark); + else + save_yank(rl_point, rl_mark - rl_point); + + return CSstay; +} + +static el_status_t move_to_char(void) +{ + int i, c; + char *p; + + if ((c = tty_get()) == EOF) + return CSeof; + + for (i = rl_point + 1, p = &rl_line_buffer[i]; i < rl_end; i++, p++) { + if (*p == c) { + rl_point = i; + return CSmove; + } + } + + return CSstay; +} + +static el_status_t fd_kill_word(void) +{ + int i; + + do_forward(CSstay); + if (old_point != rl_point) { + i = rl_point - old_point - 1; + rl_point = old_point; + return delete_string(i); + } + + return CSstay; +} + +static el_status_t bk_kill_word(void) +{ + bk_word(); + if (old_point != rl_point) + return delete_string(old_point - rl_point); + + return CSstay; +} + +static int argify(char *line, char ***avp) +{ + char *c; + char **p; + char **arg; + int ac; + int i; + + i = MEM_INC; + *avp = p = malloc(sizeof(char *) * i); + if (!p) + return 0; + + for (c = line; isspace(*c); c++) + continue; + + if (*c == '\n' || *c == '\0') + return 0; + + for (ac = 0, p[ac++] = c; *c && *c != '\n'; ) { + if (!isspace(*c)) { + c++; + continue; + } + + *c++ = '\0'; + if (*c && *c != '\n') { + if (ac + 1 == i) { + arg = malloc(sizeof(char *) * (i + MEM_INC)); + if (!arg) { + p[ac] = NULL; + return ac; + } + + memcpy(arg, p, i * sizeof(char *)); + i += MEM_INC; + free(p); + *avp = p = arg; + } + p[ac++] = c; + } + } + + *c = '\0'; + p[ac] = NULL; + + return ac; +} + +static el_status_t last_argument(void) +{ + char **av = NULL; + char *p; + el_status_t s; + int ac; + + if (H.Size == 1 || (p = (char *)H.Lines[H.Size - 2]) == NULL) + return el_ring_bell(); + + p = strdup(p); + if (!p) + return CSstay; + + ac = argify(p, &av); + if (Repeat != NO_ARG) + s = Repeat < ac ? insert_string(av[Repeat]) : el_ring_bell(); + else + s = ac ? insert_string(av[ac - 1]) : CSstay; + + if (av) + free(av); + free(p); + + return s; +} + +static el_keymap_t Map[64] = { + { CTL('@'), mk_set }, + { CTL('A'), beg_line }, + { CTL('B'), bk_char }, + { CTL('D'), del_char }, + { CTL('E'), end_line }, + { CTL('F'), fd_char }, + { CTL('G'), el_ring_bell }, + { CTL('H'), bk_del_char }, + { CTL('I'), c_complete }, + { CTL('J'), accept_line }, + { CTL('K'), kill_line }, + { CTL('L'), refresh }, + { CTL('M'), accept_line }, + { CTL('N'), h_next }, + { CTL('O'), el_ring_bell }, + { CTL('P'), h_prev }, + { CTL('Q'), el_ring_bell }, + { CTL('R'), h_search }, + { CTL('S'), el_ring_bell }, + { CTL('T'), transpose }, + { CTL('U'), el_ring_bell }, + { CTL('V'), quote }, + { CTL('W'), bk_kill_word }, + { CTL('X'), exchange }, + { CTL('Y'), yank }, +#ifdef SYSTEM_IS_WIN32 + { CTL('Z'), end_of_input }, +#else + { CTL('Z'), el_ring_bell }, +#endif + { CTL('['), meta }, + { CTL(']'), move_to_char }, + { CTL('^'), el_ring_bell }, + { CTL('_'), el_ring_bell }, + { 0, NULL } +}; + +static el_keymap_t MetaMap[64]= { + { CTL('H'), bk_kill_word }, + { DEL, bk_kill_word }, + { ' ', mk_set }, + { '.', last_argument }, + { '<', h_first }, + { '>', h_last }, + { '?', c_possible }, + { 'b', bk_word }, + { 'c', case_cap_word }, + { 'd', fd_kill_word }, + { 'f', fd_word }, + { 'l', case_down_word }, + { 'm', toggle_meta_mode }, + { 'u', case_up_word }, + { 'y', yank }, + { 'w', copy_region }, + { 0, NULL } +}; + +static size_t find_key_in_map(int key, el_keymap_t map[], size_t mapsz) +{ + size_t i; + + for (i = 0; map[i].Function && i < mapsz; i++) { + if (map[i].Key == key) + return i; + } + + if (i < mapsz) + return i; + + return mapsz; +} + +static el_status_t el_bind_key_in_map(int key, el_keymap_func_t function, el_keymap_t map[], size_t mapsz) +{ + size_t creat, pos = find_key_in_map(key, map, mapsz); + + /* Must check that pos is not the next to last array position, + * otherwise we will write out-of-bounds to terminate the list. */ + if (pos + 1 >= mapsz) { + errno = ENOMEM; + return CSeof; + } + + /* Add at end, create new? */ + creat = map[pos].Function == NULL; + + /* A new key so have to add it to end */ + map[pos].Key = key; + map[pos].Function = function; + + /* Terminate list */ + if (creat) { + map[pos + 1].Key = 0; + map[pos + 1].Function = NULL; + } + + return CSdone; +} + +el_status_t el_bind_key(int key, el_keymap_func_t function) +{ + return el_bind_key_in_map(key, function, Map, NELEMS(Map)); +} + +el_status_t el_bind_key_in_metamap(int key, el_keymap_func_t function) +{ + return el_bind_key_in_map(key, function, MetaMap, NELEMS(MetaMap)); +} + +rl_getc_func_t *rl_set_getc_func(rl_getc_func_t *func) +{ + rl_getc_func_t *old = rl_getc_function; + rl_getc_function = func; + return old; +} + +/** + * Local Variables: + * c-file-style: "k&r" + * c-basic-offset: 4 + * End: + */ diff --git a/vendor/editline/src/editline.h b/vendor/editline/src/editline.h new file mode 100644 index 0000000..d11b6e6 --- /dev/null +++ b/vendor/editline/src/editline.h @@ -0,0 +1,101 @@ +/* Internal header file for editline library. + * + * Copyright (c) 1992, 1993 Simmule Turner and Rich Salz + * All rights reserved. + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or of the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * 1. The authors are not responsible for the consequences of use of this + * software, no matter how awful, even if they arise from flaws in it. + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Since few users ever read sources, + * credits must appear in the documentation. + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. Since few users + * ever read sources, credits must appear in the documentation. + * 4. This notice may not be removed or altered. + */ + +#ifndef EDITLINE_PRIVATE_H_ +#define EDITLINE_PRIVATE_H_ + +#include +#include +#ifdef HAVE_MALLOC_H +#include +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_DIRENT_H +#include +#endif +#ifdef HAVE_SIGNAL_H +#include +#endif +#ifdef SYS_UNIX +#include "unix.h" +#endif +#ifdef SYS_OS9 +#include "os9.h" +#endif +/* The following two are for TIOCGWINSZ */ +#ifdef HAVE_TERMIOS_H +# include +#endif +#ifdef GWINSZ_IN_SYS_IOCTL +# include +#endif + +#define MEM_INC 64 +#define SCREEN_INC 256 + +/* From The Practice of Programming, by Kernighan and Pike */ +#ifndef NELEMS +#define NELEMS(array) (sizeof(array) / sizeof(array[0])) +#endif + +/* +** Variables and routines internal to this package. +*/ +extern int rl_eof; +extern int rl_erase; +extern int rl_intr; +extern int rl_kill; +extern int rl_quit; +#ifdef CONFIG_SIGSTOP +extern int rl_susp; +#endif +void rl_ttyset(int Reset); +void rl_add_slash(char *path, char *p); +char *rl_complete(char *token, int *match); +int rl_list_possib(char *token, char ***av); + +#ifndef HAVE_STDLIB_H +extern char *getenv(const char *name); +extern char *malloc(size_t size); +extern char *realloc(void *ptr, size_t size); +extern char *memcpy(void *dest, const void *src, size_t n); +extern char *strcat(char *dest, const char *src); +extern char *strchr(const char *s, int c); +extern char *strrchr(const char *s, int c); +extern char *strcpy(char *dest, const char *src); +extern char *strdup(const char *s); +extern int strcmp(const char *s1, const char *s2); +extern int strlen(const char *s); +extern int strncmp(const char *s1, const char *s2, size_t n); +#endif/* !HAVE_STDLIB_H */ + +#ifndef HAVE_STRDUP +extern char *strdup(const char *s); +#endif + +#include "../include/editline.h" +#endif /* EDITLINE_PRIVATE_H_ */ diff --git a/vendor/editline/src/os9.h b/vendor/editline/src/os9.h new file mode 100644 index 0000000..78b52c4 --- /dev/null +++ b/vendor/editline/src/os9.h @@ -0,0 +1,26 @@ +/* Editline system header file for OS-9 (on 68k). + * + * Copyright (c) 1992, 1993 Simmule Turner and Rich Salz + * All rights reserved. + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or of the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * 1. The authors are not responsible for the consequences of use of this + * software, no matter how awful, even if they arise from flaws in it. + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Since few users ever read sources, + * credits must appear in the documentation. + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. Since few users + * ever read sources, credits must appear in the documentation. + * 4. This notice may not be removed or altered. + */ + +#define CRLF "\r\l" + +#include +typedef struct direct DIRENTRY; diff --git a/vendor/editline/src/project_editline-build/examples/cli b/vendor/editline/src/project_editline-build/examples/cli new file mode 100755 index 0000000..f3e5650 Binary files /dev/null and b/vendor/editline/src/project_editline-build/examples/cli differ diff --git a/vendor/editline/src/project_editline-build/examples/excallback b/vendor/editline/src/project_editline-build/examples/excallback new file mode 100755 index 0000000..d52ab13 Binary files /dev/null and b/vendor/editline/src/project_editline-build/examples/excallback differ diff --git a/vendor/editline/src/project_editline-build/examples/fileman b/vendor/editline/src/project_editline-build/examples/fileman new file mode 100755 index 0000000..b962e30 Binary files /dev/null and b/vendor/editline/src/project_editline-build/examples/fileman differ diff --git a/vendor/editline/src/project_editline-build/examples/testit b/vendor/editline/src/project_editline-build/examples/testit new file mode 100755 index 0000000..06b8518 Binary files /dev/null and b/vendor/editline/src/project_editline-build/examples/testit differ diff --git a/vendor/editline/src/project_editline-build/src/.libs/libeditline.so.1 b/vendor/editline/src/project_editline-build/src/.libs/libeditline.so.1 new file mode 120000 index 0000000..c77e82e --- /dev/null +++ b/vendor/editline/src/project_editline-build/src/.libs/libeditline.so.1 @@ -0,0 +1 @@ +libeditline.so.1.0.0 \ No newline at end of file diff --git a/vendor/editline/src/project_editline-build/src/.libs/libeditline.so.1.0.0 b/vendor/editline/src/project_editline-build/src/.libs/libeditline.so.1.0.0 new file mode 100755 index 0000000..09a7dba Binary files /dev/null and b/vendor/editline/src/project_editline-build/src/.libs/libeditline.so.1.0.0 differ diff --git a/vendor/editline/src/project_editline-stamp/project_editline-autogen b/vendor/editline/src/project_editline-stamp/project_editline-autogen new file mode 100644 index 0000000..e69de29 diff --git a/vendor/editline/src/project_editline-stamp/project_editline-build b/vendor/editline/src/project_editline-stamp/project_editline-build new file mode 100644 index 0000000..e69de29 diff --git a/vendor/editline/src/project_editline-stamp/project_editline-configure b/vendor/editline/src/project_editline-stamp/project_editline-configure new file mode 100644 index 0000000..e69de29 diff --git a/vendor/editline/src/project_editline-stamp/project_editline-done b/vendor/editline/src/project_editline-stamp/project_editline-done new file mode 100644 index 0000000..e69de29 diff --git a/vendor/editline/src/project_editline-stamp/project_editline-download b/vendor/editline/src/project_editline-stamp/project_editline-download new file mode 100644 index 0000000..e69de29 diff --git a/vendor/editline/src/project_editline-stamp/project_editline-install b/vendor/editline/src/project_editline-stamp/project_editline-install new file mode 100644 index 0000000..e69de29 diff --git a/vendor/editline/src/project_editline-stamp/project_editline-mkdir b/vendor/editline/src/project_editline-stamp/project_editline-mkdir new file mode 100644 index 0000000..e69de29 diff --git a/vendor/editline/src/project_editline-stamp/project_editline-patch b/vendor/editline/src/project_editline-stamp/project_editline-patch new file mode 100644 index 0000000..e69de29 diff --git a/vendor/editline/src/project_editline-stamp/project_editline-update b/vendor/editline/src/project_editline-stamp/project_editline-update new file mode 100644 index 0000000..e69de29 diff --git a/vendor/editline/src/sysos9.c b/vendor/editline/src/sysos9.c new file mode 100644 index 0000000..334ef17 --- /dev/null +++ b/vendor/editline/src/sysos9.c @@ -0,0 +1,64 @@ +/* OS-9 (on 68k) system-dependant routines for editline library. + * + * Copyright (c) 1992, 1993 Simmule Turner and Rich Salz + * All rights reserved. + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or of the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * 1. The authors are not responsible for the consequences of use of this + * software, no matter how awful, even if they arise from flaws in it. + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Since few users ever read sources, + * credits must appear in the documentation. + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. Since few users + * ever read sources, credits must appear in the documentation. + * 4. This notice may not be removed or altered. + */ +#include "editline.h" +#include +#include + +void rl_ttyset(int Reset) +{ + static struct sgbuf old; + struct sgbuf new; + + if (Reset == 0) { + _gs_opt(0, &old); + _gs_opt(0, &new); + new.sg_backsp = 0; new.sg_delete = 0; new.sg_echo = 0; + new.sg_alf = 0; new.sg_nulls = 0; new.sg_pause = 0; + new.sg_page = 0; new.sg_bspch = 0; new.sg_dlnch = 0; + new.sg_eorch = 0; new.sg_eofch = 0; new.sg_rlnch = 0; + new.sg_dulnch = 0; new.sg_psch = 0; new.sg_kbich = 0; + new.sg_kbach = 0; new.sg_bsech = 0; new.sg_bellch = 0; + new.sg_xon = 0; new.sg_xoff = 0; new.sg_tabcr = 0; + new.sg_tabsiz = 0; + _ss_opt(0, &new); + rl_erase = old.sg_bspch; + rl_kill = old.sg_dlnch; + rl_eof = old.sg_eofch; + rl_intr = old.sg_kbich; + rl_quit = -1; + } + else { + _ss_opt(0, &old); + } +} + +void rl_add_slash(char *path, char *p) +{ + strcat(p, access(path, S_IREAD | S_IFDIR) ? " " : "/"); +} + +/** + * Local Variables: + * c-file-style: "k&r" + * c-basic-offset: 4 + * End: + */ diff --git a/vendor/editline/src/sysunix.c b/vendor/editline/src/sysunix.c new file mode 100644 index 0000000..4699496 --- /dev/null +++ b/vendor/editline/src/sysunix.c @@ -0,0 +1,251 @@ +/* Unix system-dependant routines for editline library. + * + * Copyright (c) 1992, 1993 Simmule Turner and Rich Salz + * All rights reserved. + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or of the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * 1. The authors are not responsible for the consequences of use of this + * software, no matter how awful, even if they arise from flaws in it. + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Since few users ever read sources, + * credits must appear in the documentation. + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. Since few users + * ever read sources, credits must appear in the documentation. + * 4. This notice may not be removed or altered. + */ + +#include +#include "editline.h" + +#ifndef HAVE_TCGETATTR +/* Wrapper for ioctl syscalls to restart on signal */ +static int ioctl_wrap(int fd, int req, void *arg) +{ + int result, retries = 3; + + while (-1 == (result = ioctl(fd, req, arg)) && retries > 0) { + retries--; + + if (EINTR == errno) + continue; + + break; + } + + return result; +} +#endif + +/* Prefer termios over the others since it is likely the most portable. */ +#if defined(HAVE_TCGETATTR) +#include + +/* Wrapper for tcgetattr */ +static int getattr(int fd, struct termios *arg) +{ + int result, retries = 3; + + while (-1 == (result = tcgetattr(fd, arg)) && retries > 0) { + retries--; + + if (EINTR == errno) + continue; + + break; + } + + return result; +} + +/* Wrapper for tcgetattr */ +static int setattr(int fd, int opt, const struct termios *arg) +{ + int result, retries = 3; + + while (-1 == (result = tcsetattr(fd, opt, arg)) && retries > 0) { + retries--; + + if (EINTR == errno) + continue; + + break; + } + + return result; +} + +void rl_ttyset(int Reset) +{ + static struct termios old; + struct termios new; + + if (!Reset) { + if (-1 == getattr(0, &old)) + perror("Failed tcgetattr()"); + + rl_erase = old.c_cc[VERASE]; + rl_kill = old.c_cc[VKILL]; + rl_eof = old.c_cc[VEOF]; + rl_intr = old.c_cc[VINTR]; + rl_quit = old.c_cc[VQUIT]; +#ifdef CONFIG_SIGSTOP + rl_susp = old.c_cc[VSUSP]; +#endif + + new = old; + new.c_lflag &= ~(ECHO | ICANON | ISIG); + new.c_iflag &= ~INPCK; + if (rl_meta_chars) + new.c_iflag |= ISTRIP; + else + new.c_iflag &= ~ISTRIP; + new.c_cc[VMIN] = 1; + new.c_cc[VTIME] = 0; + if (-1 == setattr(0, TCSADRAIN, &new)) + perror("Failed tcsetattr(TCSADRAIN)"); + } else { + if (-1 == setattr(0, TCSADRAIN, &old)) + perror("Failed tcsetattr(TCSADRAIN)"); + } +} + +#elif defined(HAVE_TERMIO_H) +#include + +void rl_ttyset(int Reset) +{ + static struct termio old; + struct termio new; + + if (!Reset) { + if (-1 == ioctl_wrap(0, TCGETA, &old)) + perror("Failed ioctl(TCGETA)"); + + rl_erase = old.c_cc[VERASE]; + rl_kill = old.c_cc[VKILL]; + rl_eof = old.c_cc[VEOF]; + rl_intr = old.c_cc[VINTR]; + rl_quit = old.c_cc[VQUIT]; +#ifdef CONFIG_SIGSTOP + rl_susp = old.c_cc[VSUSP]; +#endif + + new = old; + new.c_lflag &= ~(ECHO | ICANON | ISIG); + new.c_iflag &= ~INPCK; + if (rl_meta_chars) + new.c_iflag |= ISTRIP; + else + new.c_iflag &= ~ISTRIP; + + new.c_cc[VMIN] = 1; + new.c_cc[VTIME] = 0; + if (-1 == ioctl_wrap(0, TCSETAW, &new)) + perror("Failed ioctl(TCSETAW)"); + } else { + if (-1 == ioctl_wrap(0, TCSETAW, &old)) + perror("Failed ioctl(TCSETAW)"); + } +} + +#elif defined(HAVE_SGTTY_H) +#include + +void rl_ttyset(int Reset) +{ + static struct sgttyb old_sgttyb; + static struct tchars old_tchars; + struct sgttyb new_sgttyb; + struct tchars new_tchars; +#ifdef CONFIG_SIGSTOP + struct ltchars old_ltchars; +#endif + + if (!Reset) { + if (-1 == ioctl_wrap(0, TIOCGETP, &old_sgttyb)) + perror("Failed TIOCGETP"); + + rl_erase = old_sgttyb.sg_erase; + rl_kill = old_sgttyb.sg_kill; + + if (-1 == ioctl_wrap(0, TIOCGETC, &old_tchars)) + perror("Failed TIOCGETC"); + + rl_eof = old_tchars.t_eofc; + rl_intr = old_tchars.t_intrc; + rl_quit = old_tchars.t_quitc; + +#ifdef CONFIG_SIGSTOP + if (-1 == ioctl_wrap(0, TIOCGLTC, &old_ltchars)) + perror("Failed TIOCGLTC"); + + rl_susp = old_ltchars.t_suspc; +#endif + + new_sgttyb = old_sgttyb; + new_sgttyb.sg_flags &= ~ECHO; + new_sgttyb.sg_flags |= RAW; + if (rl_meta_chars) + new_sgttyb.sg_flags &= ~PASS8; + else + new_sgttyb.sg_flags |= PASS8; + + if (-1 == ioctl_wrap(0, TIOCSETP, &new_sgttyb)) + perror("Failed TIOCSETP"); + + new_tchars = old_tchars; + new_tchars.t_intrc = -1; + new_tchars.t_quitc = -1; + if (-1 == ioctl_wrap(0, TIOCSETC, &new_tchars)) + perror("Failed TIOCSETC"); + } else { + if (-1 == ioctl_wrap(0, TIOCSETP, &old_sgttyb)) + perror("Failed TIOCSETP"); + + if (-1 == ioctl_wrap(0, TIOCSETC, &old_tchars)) + perror("Failed TIOCSETC"); + } +} +#else /* Neither HAVE_SGTTY_H, HAVE_TERMIO_H or HAVE_TCGETATTR */ +#error Unsupported platform, missing tcgetattr(), termio.h and sgtty.h +#endif /* Neither HAVE_SGTTY_H, HAVE_TERMIO_H or HAVE_TCGETATTR */ + +#ifndef HAVE_STRDUP +/* Return an allocated copy of a string. */ +char *strdup(const char *s) +{ + size_t len; + char *ptr; + + if (!s) + return NULL; + + len = strlen(s) + 1; + ptr = malloc(len); + if (ptr) + return memcpy(ptr, s, len); + + return NULL; +} +#endif + +void rl_add_slash(char *path, char *p) +{ + struct stat Sb; + + if (stat(path, &Sb) >= 0) + strcat(p, S_ISDIR(Sb.st_mode) ? "/" : " "); +} + +/** + * Local Variables: + * c-file-style: "k&r" + * c-basic-offset: 4 + * End: + */ diff --git a/vendor/editline/src/unix.h b/vendor/editline/src/unix.h new file mode 100644 index 0000000..8ab8f10 --- /dev/null +++ b/vendor/editline/src/unix.h @@ -0,0 +1,36 @@ +/* Editline system header file for Unix. + * + * Copyright (c) 1992, 1993 Simmule Turner and Rich Salz + * All rights reserved. + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or of the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * 1. The authors are not responsible for the consequences of use of this + * software, no matter how awful, even if they arise from flaws in it. + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Since few users ever read sources, + * credits must appear in the documentation. + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. Since few users + * ever read sources, credits must appear in the documentation. + * 4. This notice may not be removed or altered. + */ + +#ifndef EDITLINE_UNIX_H_ +#define EDITLINE_UNIX_H_ + +#define CRLF "\r\n" +#define FORWARD STATIC + +#include +#include +#include + +#include +typedef struct dirent DIRENTRY; + +#endif /* EDITLINE_UNIX_H_ */ diff --git a/vendor/editline/tmp/project_editline-cfgcmd.txt b/vendor/editline/tmp/project_editline-cfgcmd.txt new file mode 100644 index 0000000..576f707 --- /dev/null +++ b/vendor/editline/tmp/project_editline-cfgcmd.txt @@ -0,0 +1 @@ +cmd='/home/pbattu/freelance/gitlab/peerplays/libraries/fc/vendor/editline/configure;--prefix=/home/pbattu/freelance/gitlab/peerplays/libraries/fc/vendor/editline' diff --git a/vendor/editline/tmp/project_editline-cfgcmd.txt.in b/vendor/editline/tmp/project_editline-cfgcmd.txt.in new file mode 100644 index 0000000..b3f09ef --- /dev/null +++ b/vendor/editline/tmp/project_editline-cfgcmd.txt.in @@ -0,0 +1 @@ +cmd='@cmd@'