mirror of
https://github.com/holub/mame
synced 2025-10-04 08:28:39 +03:00
linenoise: replace linenoise-ng with a different port that is simpler and uses a different UTF8 parser [Carl]
plugins/console: better completions [Carl]
This commit is contained in:
parent
3553a7bf42
commit
4ebc18aeec
13
3rdparty/linenoise-ng/.gitignore
vendored
13
3rdparty/linenoise-ng/.gitignore
vendored
@ -1,13 +0,0 @@
|
|||||||
CMakeCache.txt
|
|
||||||
CMakeFiles
|
|
||||||
Makefile
|
|
||||||
build
|
|
||||||
cmake_install.cmake
|
|
||||||
install_manifest.txt
|
|
||||||
example
|
|
||||||
linenoise_example
|
|
||||||
liblinenoise.a
|
|
||||||
*.dSYM
|
|
||||||
history.txt
|
|
||||||
*.o
|
|
||||||
*~
|
|
120
3rdparty/linenoise-ng/CMakeLists.txt
vendored
120
3rdparty/linenoise-ng/CMakeLists.txt
vendored
@ -1,120 +0,0 @@
|
|||||||
# -*- mode: CMAKE; -*-
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.6)
|
|
||||||
|
|
||||||
project(linenoise)
|
|
||||||
|
|
||||||
set(CMAKE_BINARY_DIR "${CMAKE_SOURCE_DIR}/build")
|
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
|
||||||
set(CMAKE_BUILD_TYPE Release CACHE string "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
message(STATUS "Build mode: ${CMAKE_BUILD_TYPE}")
|
|
||||||
|
|
||||||
# INFO
|
|
||||||
set(LINENOISE_VERSION "1.0.0" CACHE path "Linenoise version")
|
|
||||||
set(LINENOISE_DISPLAY_NAME "Linenoise-NG")
|
|
||||||
set(LINENOISE_URL_INFO_ABOUT "https://github.com/arangodb/linenoise-ng")
|
|
||||||
set(LINENOISE_CONTACT "hackers@arangodb.org")
|
|
||||||
set(LINENOISE_FRIENDLY_STRING "Linenoise NG - Linenoise Next Generation")
|
|
||||||
|
|
||||||
# compiler options
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
|
||||||
message(STATUS "Compiler type GNU: ${CMAKE_CXX_COMPILER}")
|
|
||||||
set(BASE_COMPILER_OPTIONS "-std=c++11 -Wall -Wextra")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${BASE_COMPILER_OPTIONS}")
|
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${BASE_COMPILER_OPTIONS} -O0 -g")
|
|
||||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${BASE_COMPILER_OPTIONS} -Os")
|
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${BASE_COMPILER_OPTIONS} -O3 -fomit-frame-pointer")
|
|
||||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${BASE_COMPILER_OPTIONS} -O3 -g")
|
|
||||||
|
|
||||||
elseif(CMAKE_COMPILER_IS_CLANGCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
||||||
# using regular Clang or AppleClang
|
|
||||||
message(STATUS "Compiler type CLANG: ${CMAKE_CXX_COMPILER}")
|
|
||||||
set(BASE_COMPILER_OPTIONS "-std=c++11 -Wall -Wextra")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${BASE_COMPILER_OPTIONS}")
|
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${BASE_COMPILER_OPTIONS} -O0 -g")
|
|
||||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${BASE_COMPILER_OPTIONS} -Os")
|
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${BASE_COMPILER_OPTIONS} -O3 -fomit-frame-pointer")
|
|
||||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${BASE_COMPILER_OPTIONS} -O3 -g")
|
|
||||||
|
|
||||||
elseif(MSVC)
|
|
||||||
message(STATUS "Compiler type MSVC: ${CMAKE_CXX_COMPILER}")
|
|
||||||
add_definitions("-D_CRT_SECURE_NO_WARNINGS=1")
|
|
||||||
|
|
||||||
foreach (flag_var
|
|
||||||
CMAKE_CXX_FLAGS
|
|
||||||
CMAKE_CXX_FLAGS_DEBUG
|
|
||||||
CMAKE_CXX_FLAGS_RELEASE
|
|
||||||
CMAKE_CXX_FLAGS_MINSIZEREL
|
|
||||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
|
||||||
if (flag_var MATCHES "DEBUG")
|
|
||||||
set(${flag_var} "${${flag_var}} /MTd")
|
|
||||||
else ()
|
|
||||||
set(${flag_var} "${${flag_var}} /MT")
|
|
||||||
endif ()
|
|
||||||
endforeach()
|
|
||||||
# https://msdn.microsoft.com/en-us/library/aa267384%28VS.60%29.aspx
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /INCREMENTAL:NO /SUBSYSTEM:CONSOLE /LTCG /ignore:4099 /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:msvcrtd.lib")
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} /SUBSYSTEM:CONSOLE /ignore:4099 /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:msvcrtd.lib")
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /SUBSYSTEM:CONSOLE /ignore:4099 /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:msvcrtd.lib")
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /SUBSYSTEM:CONSOLE /ignore:4099 /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:msvcrtd.lib")
|
|
||||||
else()
|
|
||||||
# unknown compiler
|
|
||||||
message(STATUS "Compiler type UNKNOWN: ${CMAKE_CXX_COMPILER}")
|
|
||||||
set(BASE_COMPILER_OPTIONS "-std=c++11 -Wall -Wextra")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${BASE_COMPILER_OPTIONS}")
|
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${BASE_COMPILER_OPTIONS} -O0 -g")
|
|
||||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${BASE_COMPILER_OPTIONS} -Os")
|
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${BASE_COMPILER_OPTIONS} -O3 -fomit-frame-pointer")
|
|
||||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${BASE_COMPILER_OPTIONS} -O3 -g")
|
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include_directories(${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/src)
|
|
||||||
|
|
||||||
# build liblinenoise
|
|
||||||
add_library(
|
|
||||||
linenoise
|
|
||||||
STATIC
|
|
||||||
src/ConvertUTF.cpp
|
|
||||||
src/linenoise.cpp
|
|
||||||
src/wcwidth.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
# install
|
|
||||||
install(TARGETS linenoise DESTINATION lib)
|
|
||||||
|
|
||||||
# headers
|
|
||||||
install(FILES include/linenoise.h DESTINATION include)
|
|
||||||
|
|
||||||
# build example
|
|
||||||
add_executable(
|
|
||||||
example
|
|
||||||
tst/example.c
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(
|
|
||||||
example
|
|
||||||
linenoise
|
|
||||||
)
|
|
||||||
|
|
||||||
# packaging
|
|
||||||
include(CPack)
|
|
||||||
|
|
||||||
if (MSVC)
|
|
||||||
else ()
|
|
||||||
set(CPACK_SET_DESTDIR ON)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
set(CPACK_PACKAGE_VENDOR "ArangoDB GmbH")
|
|
||||||
set(CPACK_PACKAGE_CONTACT "info@arangodb.com")
|
|
||||||
set(CPACK_PACKAGE_VERSION "${LINENOISE_VERSION}")
|
|
||||||
|
|
||||||
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
|
|
||||||
|
|
||||||
set(CPACK_STRIP_FILES "ON")
|
|
||||||
|
|
||||||
set(CPACK_PACKAGE_NAME "linenoise")
|
|
||||||
set(CPACK_DEBIAN_PACKAGE_SECTION "utilities")
|
|
66
3rdparty/linenoise-ng/LICENSE
vendored
66
3rdparty/linenoise-ng/LICENSE
vendored
@ -1,66 +0,0 @@
|
|||||||
linenoise.cpp
|
|
||||||
=============
|
|
||||||
|
|
||||||
Copyright (c) 2010, Salvatore Sanfilippo <antirez at gmail dot com>
|
|
||||||
Copyright (c) 2010, Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
|
||||||
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of Redis nor the names of its contributors may be used
|
|
||||||
to endorse or promote products derived from this software without
|
|
||||||
specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
||||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
|
|
||||||
wcwidth.cpp
|
|
||||||
===========
|
|
||||||
|
|
||||||
Markus Kuhn -- 2007-05-26 (Unicode 5.0)
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and distribute this software
|
|
||||||
for any purpose and without fee is hereby granted. The author
|
|
||||||
disclaims all warranties with regard to this software.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ConvertUTF.cpp
|
|
||||||
==============
|
|
||||||
|
|
||||||
Copyright 2001-2004 Unicode, Inc.
|
|
||||||
|
|
||||||
Disclaimer
|
|
||||||
|
|
||||||
This source code is provided as is by Unicode, Inc. No claims are
|
|
||||||
made as to fitness for any particular purpose. No warranties of any
|
|
||||||
kind are expressed or implied. The recipient agrees to determine
|
|
||||||
applicability of information provided. If this file has been
|
|
||||||
purchased on magnetic or optical media from Unicode, Inc., the
|
|
||||||
sole remedy for any claim will be exchange of defective media
|
|
||||||
within 90 days of receipt.
|
|
||||||
|
|
||||||
Limitations on Rights to Redistribute This Code
|
|
||||||
|
|
||||||
Unicode, Inc. hereby grants the right to freely use the information
|
|
||||||
supplied in this file in the creation of products supporting the
|
|
||||||
Unicode Standard, and to make copies of this file in any form
|
|
||||||
for internal or external distribution as long as this notice
|
|
||||||
remains attached.
|
|
156
3rdparty/linenoise-ng/README.md
vendored
156
3rdparty/linenoise-ng/README.md
vendored
@ -1,156 +0,0 @@
|
|||||||
# Linenoise Next Generation
|
|
||||||
|
|
||||||
A small, portable GNU readline replacement for Linux, Windows and
|
|
||||||
MacOS which is capable of handling UTF-8 characters. Unlike GNU
|
|
||||||
readline, which is GPL, this library uses a BSD license and can be
|
|
||||||
used in any kind of program.
|
|
||||||
|
|
||||||
## Origin
|
|
||||||
|
|
||||||
This linenoise implementation is based on the work by
|
|
||||||
[Salvatore Sanfilippo](https://github.com/antirez/linenoise) and
|
|
||||||
10gen Inc. The goal is to create a zero-config, BSD
|
|
||||||
licensed, readline replacement usable in Apache2 or BSD licensed
|
|
||||||
programs.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
* single-line and multi-line editing mode with the usual key bindings implemented
|
|
||||||
* history handling
|
|
||||||
* completion
|
|
||||||
* BSD license source code
|
|
||||||
* Only uses a subset of VT100 escapes (ANSI.SYS compatible)
|
|
||||||
* UTF8 aware
|
|
||||||
* support for Linux, MacOS and Windows
|
|
||||||
|
|
||||||
It deviates from Salvatore's original goal to have a minimal readline
|
|
||||||
replacement for the sake of supporting UTF8 and Windows. It deviates
|
|
||||||
from 10gen Inc.'s goal to create a C++ interface to linenoise. This
|
|
||||||
library uses C++ internally, but to the user it provides a pure C
|
|
||||||
interface that is compatible with the original linenoise API.
|
|
||||||
C interface.
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
To build this library, you will need a C++11-enabled compiler and
|
|
||||||
some recent version of CMake.
|
|
||||||
|
|
||||||
## Build instructions
|
|
||||||
|
|
||||||
To build this library on Linux, first create a build directory
|
|
||||||
|
|
||||||
```bash
|
|
||||||
mkdir -p build
|
|
||||||
```
|
|
||||||
|
|
||||||
and then build the library:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
(cd build && cmake -DCMAKE_BUILD_TYPE=Release .. && make)
|
|
||||||
```
|
|
||||||
|
|
||||||
To build and install the library at the default target location, use
|
|
||||||
|
|
||||||
```bash
|
|
||||||
(cd build && cmake -DCMAKE_BUILD_TYPE=Release .. && make && sudo make install)
|
|
||||||
```
|
|
||||||
|
|
||||||
The default installation location can be adjusted by setting the `DESTDIR`
|
|
||||||
variable when invoking `make install`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
(cd build && make DESTDIR=/tmp install)
|
|
||||||
```
|
|
||||||
|
|
||||||
To build the library on Windows, use these commands in an MS-DOS command
|
|
||||||
prompt:
|
|
||||||
|
|
||||||
```
|
|
||||||
md build
|
|
||||||
cd build
|
|
||||||
```
|
|
||||||
|
|
||||||
After that, invoke the appropriate command to create the files for your
|
|
||||||
target environment:
|
|
||||||
|
|
||||||
* 32 bit: `cmake -G "Visual Studio 12 2013" -DCMAKE_BUILD_TYPE=Release ..`
|
|
||||||
* 64 bit: `cmake -G "Visual Studio 12 2013 Win64" -DCMAKE_BUILD_TYPE=Release ..`
|
|
||||||
|
|
||||||
After that, open the generated file `linenoise.sln` from the `build`
|
|
||||||
subdirectory with Visual Studio.
|
|
||||||
|
|
||||||
|
|
||||||
*note: the following sections of the README.md are from the original
|
|
||||||
linenoise repository and are partly outdated*
|
|
||||||
|
|
||||||
## Can a line editing library be 20k lines of code?
|
|
||||||
|
|
||||||
Line editing with some support for history is a really important
|
|
||||||
feature for command line utilities. Instead of retyping almost the
|
|
||||||
same stuff again and again it's just much better to hit the up arrow
|
|
||||||
and edit on syntax errors, or in order to try a slightly different
|
|
||||||
command. But apparently code dealing with terminals is some sort of
|
|
||||||
Black Magic: readline is 30k lines of code, libedit 20k. Is it
|
|
||||||
reasonable to link small utilities to huge libraries just to get a
|
|
||||||
minimal support for line editing?
|
|
||||||
|
|
||||||
So what usually happens is either:
|
|
||||||
|
|
||||||
* Large programs with configure scripts disabling line editing if
|
|
||||||
readline is not present in the system, or not supporting it at all
|
|
||||||
since readline is GPL licensed and libedit (the BSD clone) is not
|
|
||||||
as known and available as readline is (Real world example of this
|
|
||||||
problem: Tclsh).
|
|
||||||
|
|
||||||
* Smaller programs not using a configure script not supporting line
|
|
||||||
editing at all (A problem we had with Redis-cli for instance).
|
|
||||||
|
|
||||||
The result is a pollution of binaries without line editing support.
|
|
||||||
|
|
||||||
So Salvatore spent more or less two hours doing a reality check
|
|
||||||
resulting in this little library: is it *really* needed for a line
|
|
||||||
editing library to be 20k lines of code? Apparently not, it is possibe
|
|
||||||
to get a very small, zero configuration, trivial to embed library,
|
|
||||||
that solves the problem. Smaller programs will just include this,
|
|
||||||
supporing line editing out of the box. Larger programs may use this
|
|
||||||
little library or just checking with configure if readline/libedit is
|
|
||||||
available and resorting to linenoise if not.
|
|
||||||
|
|
||||||
## Terminals, in 2010.
|
|
||||||
|
|
||||||
Apparently almost every terminal you can happen to use today has some
|
|
||||||
kind of support for basic VT100 escape sequences. So Salvatore tried
|
|
||||||
to write a lib using just very basic VT100 features. The resulting
|
|
||||||
library appears to work everywhere Salvatore tried to use it, and now
|
|
||||||
can work even on ANSI.SYS compatible terminals, since no VT220
|
|
||||||
specific sequences are used anymore.
|
|
||||||
|
|
||||||
The original library has currently about 1100 lines of code. In order
|
|
||||||
to use it in your project just look at the *example.c* file in the
|
|
||||||
source distribution, it is trivial. Linenoise is BSD code, so you can
|
|
||||||
use both in free software and commercial software.
|
|
||||||
|
|
||||||
## Tested with...
|
|
||||||
|
|
||||||
* Linux text only console ($TERM = linux)
|
|
||||||
* Linux KDE terminal application ($TERM = xterm)
|
|
||||||
* Linux xterm ($TERM = xterm)
|
|
||||||
* Linux Buildroot ($TERM = vt100)
|
|
||||||
* Mac OS X iTerm ($TERM = xterm)
|
|
||||||
* Mac OS X default Terminal.app ($TERM = xterm)
|
|
||||||
* OpenBSD 4.5 through an OSX Terminal.app ($TERM = screen)
|
|
||||||
* IBM AIX 6.1
|
|
||||||
* FreeBSD xterm ($TERM = xterm)
|
|
||||||
* ANSI.SYS
|
|
||||||
* Emacs comint mode ($TERM = dumb)
|
|
||||||
* Windows
|
|
||||||
|
|
||||||
Please test it everywhere you can and report back!
|
|
||||||
|
|
||||||
## Let's push this forward!
|
|
||||||
|
|
||||||
Patches should be provided in the respect of linenoise sensibility for
|
|
||||||
small and easy to understand code that and the license
|
|
||||||
restrictions. Extensions must be submitted under a BSD license-style.
|
|
||||||
A contributor license is required for contributions.
|
|
||||||
|
|
11
3rdparty/linenoise-ng/appveyor.yml
vendored
11
3rdparty/linenoise-ng/appveyor.yml
vendored
@ -1,11 +0,0 @@
|
|||||||
version: 1.0.{build}
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
configuration: Release
|
|
||||||
build:
|
|
||||||
build_script:
|
|
||||||
- md build
|
|
||||||
- cd %APPVEYOR_BUILD_FOLDER%\build
|
|
||||||
- cmake -G "Visual Studio 12 Win64" -DCMAKE_BUILD_TYPE=Release ..
|
|
||||||
- cmake --build . --config Release
|
|
71
3rdparty/linenoise-ng/include/linenoise.h
vendored
71
3rdparty/linenoise-ng/include/linenoise.h
vendored
@ -1,71 +0,0 @@
|
|||||||
/* linenoise.h -- guerrilla line editing library against the idea that a
|
|
||||||
* line editing lib needs to be 20,000 lines of C code.
|
|
||||||
*
|
|
||||||
* See linenoise.c for more information.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2010, Salvatore Sanfilippo <antirez at gmail dot com>
|
|
||||||
* Copyright (c) 2010, Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
|
||||||
*
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* * Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of Redis nor the names of its contributors may be used
|
|
||||||
* to endorse or promote products derived from this software without
|
|
||||||
* specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
||||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LINENOISE_H
|
|
||||||
#define __LINENOISE_H
|
|
||||||
|
|
||||||
#define LINENOISE_VERSION "1.0.0"
|
|
||||||
#define LINENOISE_VERSION_MAJOR 1
|
|
||||||
#define LINENOISE_VERSION_MINOR 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct linenoiseCompletions linenoiseCompletions;
|
|
||||||
|
|
||||||
typedef void(linenoiseCompletionCallback)(const char*, linenoiseCompletions*);
|
|
||||||
void linenoiseSetCompletionCallback(linenoiseCompletionCallback* fn);
|
|
||||||
void linenoiseAddCompletion(linenoiseCompletions* lc, const char* str);
|
|
||||||
|
|
||||||
char* linenoise(const char* prompt);
|
|
||||||
void linenoisePreloadBuffer(const char* preloadText);
|
|
||||||
int linenoiseHistoryAdd(const char* line);
|
|
||||||
int linenoiseHistorySetMaxLen(int len);
|
|
||||||
char* linenoiseHistoryLine(int index);
|
|
||||||
int linenoiseHistorySave(const char* filename);
|
|
||||||
int linenoiseHistoryLoad(const char* filename);
|
|
||||||
void linenoiseHistoryFree(void);
|
|
||||||
void linenoiseClearScreen(void);
|
|
||||||
void linenoiseSetMultiLine(int ml);
|
|
||||||
void linenoisePrintKeyCodes(void);
|
|
||||||
/* the following is extension to the original linenoise API */
|
|
||||||
int linenoiseInstallWindowChangeHandler(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __LINENOISE_H */
|
|
542
3rdparty/linenoise-ng/src/ConvertUTF.cpp
vendored
542
3rdparty/linenoise-ng/src/ConvertUTF.cpp
vendored
@ -1,542 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2001-2004 Unicode, Inc.
|
|
||||||
*
|
|
||||||
* Disclaimer
|
|
||||||
*
|
|
||||||
* This source code is provided as is by Unicode, Inc. No claims are
|
|
||||||
* made as to fitness for any particular purpose. No warranties of any
|
|
||||||
* kind are expressed or implied. The recipient agrees to determine
|
|
||||||
* applicability of information provided. If this file has been
|
|
||||||
* purchased on magnetic or optical media from Unicode, Inc., the
|
|
||||||
* sole remedy for any claim will be exchange of defective media
|
|
||||||
* within 90 days of receipt.
|
|
||||||
*
|
|
||||||
* Limitations on Rights to Redistribute This Code
|
|
||||||
*
|
|
||||||
* Unicode, Inc. hereby grants the right to freely use the information
|
|
||||||
* supplied in this file in the creation of products supporting the
|
|
||||||
* Unicode Standard, and to make copies of this file in any form
|
|
||||||
* for internal or external distribution as long as this notice
|
|
||||||
* remains attached.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------
|
|
||||||
|
|
||||||
Conversions between UTF32, UTF-16, and UTF-8. Source code file.
|
|
||||||
Author: Mark E. Davis, 1994.
|
|
||||||
Rev History: Rick McGowan, fixes & updates May 2001.
|
|
||||||
Sept 2001: fixed const & error conditions per
|
|
||||||
mods suggested by S. Parent & A. Lillich.
|
|
||||||
June 2002: Tim Dodd added detection and handling of incomplete
|
|
||||||
source sequences, enhanced error detection, added casts
|
|
||||||
to eliminate compiler warnings.
|
|
||||||
July 2003: slight mods to back out aggressive FFFE detection.
|
|
||||||
Jan 2004: updated switches in from-UTF8 conversions.
|
|
||||||
Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.
|
|
||||||
|
|
||||||
See the header file "ConvertUTF.h" for complete documentation.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
#include "ConvertUTF.h"
|
|
||||||
#ifdef CVTUTF_DEBUG
|
|
||||||
#include <stdio.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace linenoise_ng {
|
|
||||||
|
|
||||||
static const int halfShift = 10; /* used for shifting by 10 bits */
|
|
||||||
|
|
||||||
static const UTF32 halfBase = 0x0010000UL;
|
|
||||||
static const UTF32 halfMask = 0x3FFUL;
|
|
||||||
|
|
||||||
#define UNI_SUR_HIGH_START (UTF32)0xD800
|
|
||||||
#define UNI_SUR_HIGH_END (UTF32)0xDBFF
|
|
||||||
#define UNI_SUR_LOW_START (UTF32)0xDC00
|
|
||||||
#define UNI_SUR_LOW_END (UTF32)0xDFFF
|
|
||||||
#define false 0
|
|
||||||
#define true 1
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF32toUTF16 (
|
|
||||||
const UTF32** sourceStart, const UTF32* sourceEnd,
|
|
||||||
char16_t** targetStart, char16_t* targetEnd, ConversionFlags flags) {
|
|
||||||
ConversionResult result = conversionOK;
|
|
||||||
const UTF32* source = *sourceStart;
|
|
||||||
char16_t* target = *targetStart;
|
|
||||||
while (source < sourceEnd) {
|
|
||||||
UTF32 ch;
|
|
||||||
if (target >= targetEnd) {
|
|
||||||
result = targetExhausted; break;
|
|
||||||
}
|
|
||||||
ch = *source++;
|
|
||||||
if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
|
|
||||||
/* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
|
|
||||||
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
|
|
||||||
if (flags == strictConversion) {
|
|
||||||
--source; /* return to the illegal value itself */
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
*target++ = UNI_REPLACEMENT_CHAR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*target++ = (UTF16)ch; /* normal case */
|
|
||||||
}
|
|
||||||
} else if (ch > UNI_MAX_LEGAL_UTF32) {
|
|
||||||
if (flags == strictConversion) {
|
|
||||||
result = sourceIllegal;
|
|
||||||
} else {
|
|
||||||
*target++ = UNI_REPLACEMENT_CHAR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* target is a character in range 0xFFFF - 0x10FFFF. */
|
|
||||||
if (target + 1 >= targetEnd) {
|
|
||||||
--source; /* Back up source pointer! */
|
|
||||||
result = targetExhausted; break;
|
|
||||||
}
|
|
||||||
ch -= halfBase;
|
|
||||||
*target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
|
|
||||||
*target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*sourceStart = source;
|
|
||||||
*targetStart = target;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF16toUTF32 (
|
|
||||||
const UTF16** sourceStart, const UTF16* sourceEnd,
|
|
||||||
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
|
|
||||||
ConversionResult result = conversionOK;
|
|
||||||
const UTF16* source = *sourceStart;
|
|
||||||
UTF32* target = *targetStart;
|
|
||||||
UTF32 ch, ch2;
|
|
||||||
while (source < sourceEnd) {
|
|
||||||
const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
|
|
||||||
ch = *source++;
|
|
||||||
/* If we have a surrogate pair, convert to UTF32 first. */
|
|
||||||
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
|
|
||||||
/* If the 16 bits following the high surrogate are in the source buffer... */
|
|
||||||
if (source < sourceEnd) {
|
|
||||||
ch2 = *source;
|
|
||||||
/* If it's a low surrogate, convert to UTF32. */
|
|
||||||
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
|
|
||||||
ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
|
|
||||||
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
|
|
||||||
++source;
|
|
||||||
} else if (flags == strictConversion) { /* it's an unpaired high surrogate */
|
|
||||||
--source; /* return to the illegal value itself */
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else { /* We don't have the 16 bits following the high surrogate. */
|
|
||||||
--source; /* return to the high surrogate */
|
|
||||||
result = sourceExhausted;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (flags == strictConversion) {
|
|
||||||
/* UTF-16 surrogate values are illegal in UTF-32 */
|
|
||||||
if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
|
|
||||||
--source; /* return to the illegal value itself */
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (target >= targetEnd) {
|
|
||||||
source = oldSource; /* Back up source pointer! */
|
|
||||||
result = targetExhausted; break;
|
|
||||||
}
|
|
||||||
*target++ = ch;
|
|
||||||
}
|
|
||||||
*sourceStart = source;
|
|
||||||
*targetStart = target;
|
|
||||||
#ifdef CVTUTF_DEBUG
|
|
||||||
if (result == sourceIllegal) {
|
|
||||||
fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2);
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Index into the table below with the first byte of a UTF-8 sequence to
|
|
||||||
* get the number of trailing bytes that are supposed to follow it.
|
|
||||||
* Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
|
|
||||||
* left as-is for anyone who may want to do such conversion, which was
|
|
||||||
* allowed in earlier algorithms.
|
|
||||||
*/
|
|
||||||
static const char trailingBytesForUTF8[256] = {
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
|
||||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Magic values subtracted from a buffer value during UTF8 conversion.
|
|
||||||
* This table contains as many values as there might be trailing bytes
|
|
||||||
* in a UTF-8 sequence.
|
|
||||||
*/
|
|
||||||
static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
|
|
||||||
0x03C82080UL, 0xFA082080UL, 0x82082080UL };
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
|
|
||||||
* into the first byte, depending on how many bytes follow. There are
|
|
||||||
* as many entries in this table as there are UTF-8 sequence types.
|
|
||||||
* (I.e., one byte sequence, two byte... etc.). Remember that sequencs
|
|
||||||
* for *legal* UTF-8 will be 4 or fewer bytes total.
|
|
||||||
*/
|
|
||||||
static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* The interface converts a whole buffer to avoid function-call overhead.
|
|
||||||
* Constants have been gathered. Loops & conditionals have been removed as
|
|
||||||
* much as possible for efficiency, in favor of drop-through switches.
|
|
||||||
* (See "Note A" at the bottom of the file for equivalent code.)
|
|
||||||
* If your compiler supports it, the "isLegalUTF8" call can be turned
|
|
||||||
* into an inline function.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF16toUTF8 (
|
|
||||||
const UTF16** sourceStart, const UTF16* sourceEnd,
|
|
||||||
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
|
|
||||||
ConversionResult result = conversionOK;
|
|
||||||
const UTF16* source = *sourceStart;
|
|
||||||
UTF8* target = *targetStart;
|
|
||||||
while (source < sourceEnd) {
|
|
||||||
UTF32 ch;
|
|
||||||
unsigned short bytesToWrite = 0;
|
|
||||||
const UTF32 byteMask = 0xBF;
|
|
||||||
const UTF32 byteMark = 0x80;
|
|
||||||
const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
|
|
||||||
ch = *source++;
|
|
||||||
/* If we have a surrogate pair, convert to UTF32 first. */
|
|
||||||
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
|
|
||||||
/* If the 16 bits following the high surrogate are in the source buffer... */
|
|
||||||
if (source < sourceEnd) {
|
|
||||||
UTF32 ch2 = *source;
|
|
||||||
/* If it's a low surrogate, convert to UTF32. */
|
|
||||||
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
|
|
||||||
ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
|
|
||||||
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
|
|
||||||
++source;
|
|
||||||
} else if (flags == strictConversion) { /* it's an unpaired high surrogate */
|
|
||||||
--source; /* return to the illegal value itself */
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else { /* We don't have the 16 bits following the high surrogate. */
|
|
||||||
--source; /* return to the high surrogate */
|
|
||||||
result = sourceExhausted;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (flags == strictConversion) {
|
|
||||||
/* UTF-16 surrogate values are illegal in UTF-32 */
|
|
||||||
if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
|
|
||||||
--source; /* return to the illegal value itself */
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Figure out how many bytes the result will require */
|
|
||||||
if (ch < (UTF32)0x80) { bytesToWrite = 1;
|
|
||||||
} else if (ch < (UTF32)0x800) { bytesToWrite = 2;
|
|
||||||
} else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
|
|
||||||
} else if (ch < (UTF32)0x110000) { bytesToWrite = 4;
|
|
||||||
} else { bytesToWrite = 3;
|
|
||||||
ch = UNI_REPLACEMENT_CHAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
target += bytesToWrite;
|
|
||||||
if (target > targetEnd) {
|
|
||||||
source = oldSource; /* Back up source pointer! */
|
|
||||||
target -= bytesToWrite; result = targetExhausted; break;
|
|
||||||
}
|
|
||||||
switch (bytesToWrite) { /* note: everything falls through. */
|
|
||||||
case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
|
|
||||||
case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
|
|
||||||
case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
|
|
||||||
case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]);
|
|
||||||
}
|
|
||||||
target += bytesToWrite;
|
|
||||||
}
|
|
||||||
*sourceStart = source;
|
|
||||||
*targetStart = target;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Utility routine to tell whether a sequence of bytes is legal UTF-8.
|
|
||||||
* This must be called with the length pre-determined by the first byte.
|
|
||||||
* If not calling this from ConvertUTF8to*, then the length can be set by:
|
|
||||||
* length = trailingBytesForUTF8[*source]+1;
|
|
||||||
* and the sequence is illegal right away if there aren't that many bytes
|
|
||||||
* available.
|
|
||||||
* If presented with a length > 4, this returns false. The Unicode
|
|
||||||
* definition of UTF-8 goes up to 4-byte sequences.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static Boolean isLegalUTF8(const UTF8 *source, int length) {
|
|
||||||
UTF8 a;
|
|
||||||
const UTF8 *srcptr = source+length;
|
|
||||||
switch (length) {
|
|
||||||
default: return false;
|
|
||||||
/* Everything else falls through when "true"... */
|
|
||||||
case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
|
|
||||||
case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
|
|
||||||
case 2: if ((a = (*--srcptr)) > 0xBF) return false;
|
|
||||||
|
|
||||||
switch (*source) {
|
|
||||||
/* no fall-through in this inner switch */
|
|
||||||
case 0xE0: if (a < 0xA0) return false; break;
|
|
||||||
case 0xED: if (a > 0x9F) return false; break;
|
|
||||||
case 0xF0: if (a < 0x90) return false; break;
|
|
||||||
case 0xF4: if (a > 0x8F) return false; break;
|
|
||||||
default: if (a < 0x80) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 1: if (*source >= 0x80 && *source < 0xC2) return false;
|
|
||||||
}
|
|
||||||
if (*source > 0xF4) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Exported function to return whether a UTF-8 sequence is legal or not.
|
|
||||||
* This is not used here; it's just exported.
|
|
||||||
*/
|
|
||||||
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {
|
|
||||||
int length = trailingBytesForUTF8[*source]+1;
|
|
||||||
if (source+length > sourceEnd) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return isLegalUTF8(source, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF8toUTF16 (
|
|
||||||
const UTF8** sourceStart, const UTF8* sourceEnd,
|
|
||||||
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
|
|
||||||
ConversionResult result = conversionOK;
|
|
||||||
const UTF8* source = *sourceStart;
|
|
||||||
UTF16* target = *targetStart;
|
|
||||||
while (source < sourceEnd) {
|
|
||||||
UTF32 ch = 0;
|
|
||||||
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
|
|
||||||
if (source + extraBytesToRead >= sourceEnd) {
|
|
||||||
result = sourceExhausted; break;
|
|
||||||
}
|
|
||||||
/* Do this check whether lenient or strict */
|
|
||||||
if (! isLegalUTF8(source, extraBytesToRead+1)) {
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* The cases all fall through. See "Note A" below.
|
|
||||||
*/
|
|
||||||
switch (extraBytesToRead) {
|
|
||||||
case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
|
|
||||||
case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
|
|
||||||
case 3: ch += *source++; ch <<= 6;
|
|
||||||
case 2: ch += *source++; ch <<= 6;
|
|
||||||
case 1: ch += *source++; ch <<= 6;
|
|
||||||
case 0: ch += *source++;
|
|
||||||
}
|
|
||||||
ch -= offsetsFromUTF8[extraBytesToRead];
|
|
||||||
|
|
||||||
if (target >= targetEnd) {
|
|
||||||
source -= (extraBytesToRead+1); /* Back up source pointer! */
|
|
||||||
result = targetExhausted; break;
|
|
||||||
}
|
|
||||||
if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
|
|
||||||
/* UTF-16 surrogate values are illegal in UTF-32 */
|
|
||||||
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
|
|
||||||
if (flags == strictConversion) {
|
|
||||||
source -= (extraBytesToRead+1); /* return to the illegal value itself */
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
*target++ = UNI_REPLACEMENT_CHAR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*target++ = (UTF16)ch; /* normal case */
|
|
||||||
}
|
|
||||||
} else if (ch > UNI_MAX_UTF16) {
|
|
||||||
if (flags == strictConversion) {
|
|
||||||
result = sourceIllegal;
|
|
||||||
source -= (extraBytesToRead+1); /* return to the start */
|
|
||||||
break; /* Bail out; shouldn't continue */
|
|
||||||
} else {
|
|
||||||
*target++ = UNI_REPLACEMENT_CHAR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* target is a character in range 0xFFFF - 0x10FFFF. */
|
|
||||||
if (target + 1 >= targetEnd) {
|
|
||||||
source -= (extraBytesToRead+1); /* Back up source pointer! */
|
|
||||||
result = targetExhausted; break;
|
|
||||||
}
|
|
||||||
ch -= halfBase;
|
|
||||||
*target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
|
|
||||||
*target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*sourceStart = source;
|
|
||||||
*targetStart = target;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF32toUTF8 (
|
|
||||||
const UTF32** sourceStart, const UTF32* sourceEnd,
|
|
||||||
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
|
|
||||||
ConversionResult result = conversionOK;
|
|
||||||
const UTF32* source = *sourceStart;
|
|
||||||
UTF8* target = *targetStart;
|
|
||||||
while (source < sourceEnd) {
|
|
||||||
UTF32 ch;
|
|
||||||
unsigned short bytesToWrite = 0;
|
|
||||||
const UTF32 byteMask = 0xBF;
|
|
||||||
const UTF32 byteMark = 0x80;
|
|
||||||
ch = *source++;
|
|
||||||
if (flags == strictConversion ) {
|
|
||||||
/* UTF-16 surrogate values are illegal in UTF-32 */
|
|
||||||
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
|
|
||||||
--source; /* return to the illegal value itself */
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Figure out how many bytes the result will require. Turn any
|
|
||||||
* illegally large UTF32 things (> Plane 17) into replacement chars.
|
|
||||||
*/
|
|
||||||
if (ch < (UTF32)0x80) { bytesToWrite = 1;
|
|
||||||
} else if (ch < (UTF32)0x800) { bytesToWrite = 2;
|
|
||||||
} else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
|
|
||||||
} else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4;
|
|
||||||
} else { bytesToWrite = 3;
|
|
||||||
ch = UNI_REPLACEMENT_CHAR;
|
|
||||||
result = sourceIllegal;
|
|
||||||
}
|
|
||||||
|
|
||||||
target += bytesToWrite;
|
|
||||||
if (target > targetEnd) {
|
|
||||||
--source; /* Back up source pointer! */
|
|
||||||
target -= bytesToWrite; result = targetExhausted; break;
|
|
||||||
}
|
|
||||||
switch (bytesToWrite) { /* note: everything falls through. */
|
|
||||||
case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
|
|
||||||
case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
|
|
||||||
case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
|
|
||||||
case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
|
|
||||||
}
|
|
||||||
target += bytesToWrite;
|
|
||||||
}
|
|
||||||
*sourceStart = source;
|
|
||||||
*targetStart = target;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF8toUTF32 (
|
|
||||||
const UTF8** sourceStart, const UTF8* sourceEnd,
|
|
||||||
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
|
|
||||||
ConversionResult result = conversionOK;
|
|
||||||
const UTF8* source = *sourceStart;
|
|
||||||
UTF32* target = *targetStart;
|
|
||||||
while (source < sourceEnd) {
|
|
||||||
UTF32 ch = 0;
|
|
||||||
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
|
|
||||||
if (source + extraBytesToRead >= sourceEnd) {
|
|
||||||
result = sourceExhausted; break;
|
|
||||||
}
|
|
||||||
/* Do this check whether lenient or strict */
|
|
||||||
if (! isLegalUTF8(source, extraBytesToRead+1)) {
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* The cases all fall through. See "Note A" below.
|
|
||||||
*/
|
|
||||||
switch (extraBytesToRead) {
|
|
||||||
case 5: ch += *source++; ch <<= 6;
|
|
||||||
case 4: ch += *source++; ch <<= 6;
|
|
||||||
case 3: ch += *source++; ch <<= 6;
|
|
||||||
case 2: ch += *source++; ch <<= 6;
|
|
||||||
case 1: ch += *source++; ch <<= 6;
|
|
||||||
case 0: ch += *source++;
|
|
||||||
}
|
|
||||||
ch -= offsetsFromUTF8[extraBytesToRead];
|
|
||||||
|
|
||||||
if (target >= targetEnd) {
|
|
||||||
source -= (extraBytesToRead+1); /* Back up the source pointer! */
|
|
||||||
result = targetExhausted; break;
|
|
||||||
}
|
|
||||||
if (ch <= UNI_MAX_LEGAL_UTF32) {
|
|
||||||
/*
|
|
||||||
* UTF-16 surrogate values are illegal in UTF-32, and anything
|
|
||||||
* over Plane 17 (> 0x10FFFF) is illegal.
|
|
||||||
*/
|
|
||||||
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
|
|
||||||
if (flags == strictConversion) {
|
|
||||||
source -= (extraBytesToRead+1); /* return to the illegal value itself */
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
*target++ = UNI_REPLACEMENT_CHAR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*target++ = ch;
|
|
||||||
}
|
|
||||||
} else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
|
|
||||||
result = sourceIllegal;
|
|
||||||
*target++ = UNI_REPLACEMENT_CHAR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*sourceStart = source;
|
|
||||||
*targetStart = target;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------
|
|
||||||
|
|
||||||
Note A.
|
|
||||||
The fall-through switches in UTF-8 reading code save a
|
|
||||||
temp variable, some decrements & conditionals. The switches
|
|
||||||
are equivalent to the following loop:
|
|
||||||
{
|
|
||||||
int tmpBytesToRead = extraBytesToRead+1;
|
|
||||||
do {
|
|
||||||
ch += *source++;
|
|
||||||
--tmpBytesToRead;
|
|
||||||
if (tmpBytesToRead) ch <<= 6;
|
|
||||||
} while (tmpBytesToRead > 0);
|
|
||||||
}
|
|
||||||
In UTF-8 writing code, the switches on "bytesToWrite" are
|
|
||||||
similarly unrolled loops.
|
|
||||||
|
|
||||||
--------------------------------------------------------------------- */
|
|
162
3rdparty/linenoise-ng/src/ConvertUTF.h
vendored
162
3rdparty/linenoise-ng/src/ConvertUTF.h
vendored
@ -1,162 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2001-2004 Unicode, Inc.
|
|
||||||
*
|
|
||||||
* Disclaimer
|
|
||||||
*
|
|
||||||
* This source code is provided as is by Unicode, Inc. No claims are
|
|
||||||
* made as to fitness for any particular purpose. No warranties of any
|
|
||||||
* kind are expressed or implied. The recipient agrees to determine
|
|
||||||
* applicability of information provided. If this file has been
|
|
||||||
* purchased on magnetic or optical media from Unicode, Inc., the
|
|
||||||
* sole remedy for any claim will be exchange of defective media
|
|
||||||
* within 90 days of receipt.
|
|
||||||
*
|
|
||||||
* Limitations on Rights to Redistribute This Code
|
|
||||||
*
|
|
||||||
* Unicode, Inc. hereby grants the right to freely use the information
|
|
||||||
* supplied in this file in the creation of products supporting the
|
|
||||||
* Unicode Standard, and to make copies of this file in any form
|
|
||||||
* for internal or external distribution as long as this notice
|
|
||||||
* remains attached.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------
|
|
||||||
|
|
||||||
Conversions between UTF32, UTF-16, and UTF-8. Header file.
|
|
||||||
|
|
||||||
Several funtions are included here, forming a complete set of
|
|
||||||
conversions between the three formats. UTF-7 is not included
|
|
||||||
here, but is handled in a separate source file.
|
|
||||||
|
|
||||||
Each of these routines takes pointers to input buffers and output
|
|
||||||
buffers. The input buffers are const.
|
|
||||||
|
|
||||||
Each routine converts the text between *sourceStart and sourceEnd,
|
|
||||||
putting the result into the buffer between *targetStart and
|
|
||||||
targetEnd. Note: the end pointers are *after* the last item: e.g.
|
|
||||||
*(sourceEnd - 1) is the last item.
|
|
||||||
|
|
||||||
The return result indicates whether the conversion was successful,
|
|
||||||
and if not, whether the problem was in the source or target buffers.
|
|
||||||
(Only the first encountered problem is indicated.)
|
|
||||||
|
|
||||||
After the conversion, *sourceStart and *targetStart are both
|
|
||||||
updated to point to the end of last text successfully converted in
|
|
||||||
the respective buffers.
|
|
||||||
|
|
||||||
Input parameters:
|
|
||||||
sourceStart - pointer to a pointer to the source buffer.
|
|
||||||
The contents of this are modified on return so that
|
|
||||||
it points at the next thing to be converted.
|
|
||||||
targetStart - similarly, pointer to pointer to the target buffer.
|
|
||||||
sourceEnd, targetEnd - respectively pointers to the ends of the
|
|
||||||
two buffers, for overflow checking only.
|
|
||||||
|
|
||||||
These conversion functions take a ConversionFlags argument. When this
|
|
||||||
flag is set to strict, both irregular sequences and isolated surrogates
|
|
||||||
will cause an error. When the flag is set to lenient, both irregular
|
|
||||||
sequences and isolated surrogates are converted.
|
|
||||||
|
|
||||||
Whether the flag is strict or lenient, all illegal sequences will cause
|
|
||||||
an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
|
|
||||||
or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
|
|
||||||
must check for illegal sequences.
|
|
||||||
|
|
||||||
When the flag is set to lenient, characters over 0x10FFFF are converted
|
|
||||||
to the replacement character; otherwise (when the flag is set to strict)
|
|
||||||
they constitute an error.
|
|
||||||
|
|
||||||
Output parameters:
|
|
||||||
The value "sourceIllegal" is returned from some routines if the input
|
|
||||||
sequence is malformed. When "sourceIllegal" is returned, the source
|
|
||||||
value will point to the illegal value that caused the problem. E.g.,
|
|
||||||
in UTF-8 when a sequence is malformed, it points to the start of the
|
|
||||||
malformed sequence.
|
|
||||||
|
|
||||||
Author: Mark E. Davis, 1994.
|
|
||||||
Rev History: Rick McGowan, fixes & updates May 2001.
|
|
||||||
Fixes & updates, Sept 2001.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------
|
|
||||||
The following 4 definitions are compiler-specific.
|
|
||||||
The C standard does not guarantee that wchar_t has at least
|
|
||||||
16 bits, so wchar_t is no less portable than unsigned short!
|
|
||||||
All should be unsigned values to avoid sign extension during
|
|
||||||
bit mask & shift operations.
|
|
||||||
------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
typedef unsigned long UTF32; /* at least 32 bits */
|
|
||||||
typedef unsigned short UTF16; /* at least 16 bits */
|
|
||||||
typedef unsigned char UTF8; /* typically 8 bits */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace linenoise_ng {
|
|
||||||
|
|
||||||
typedef uint32_t UTF32;
|
|
||||||
typedef uint16_t UTF16;
|
|
||||||
typedef uint8_t UTF8;
|
|
||||||
typedef unsigned char Boolean; /* 0 or 1 */
|
|
||||||
|
|
||||||
/* Some fundamental constants */
|
|
||||||
#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
|
|
||||||
#define UNI_MAX_BMP (UTF32)0x0000FFFF
|
|
||||||
#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
|
|
||||||
#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
|
|
||||||
#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
conversionOK, /* conversion successful */
|
|
||||||
sourceExhausted, /* partial character in source, but hit end */
|
|
||||||
targetExhausted, /* insuff. room in target for conversion */
|
|
||||||
sourceIllegal /* source sequence is illegal/malformed */
|
|
||||||
} ConversionResult;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
strictConversion = 0,
|
|
||||||
lenientConversion
|
|
||||||
} ConversionFlags;
|
|
||||||
|
|
||||||
// /* This is for C++ and does no harm in C */
|
|
||||||
// #ifdef __cplusplus
|
|
||||||
// extern "C" {
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF8toUTF16 (
|
|
||||||
const UTF8** sourceStart, const UTF8* sourceEnd,
|
|
||||||
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF16toUTF8 (
|
|
||||||
const UTF16** sourceStart, const UTF16* sourceEnd,
|
|
||||||
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF8toUTF32 (
|
|
||||||
const UTF8** sourceStart, const UTF8* sourceEnd,
|
|
||||||
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF32toUTF8 (
|
|
||||||
const UTF32** sourceStart, const UTF32* sourceEnd,
|
|
||||||
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF16toUTF32 (
|
|
||||||
const UTF16** sourceStart, const UTF16* sourceEnd,
|
|
||||||
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF32toUTF16 (
|
|
||||||
const UTF32** sourceStart, const UTF32* sourceEnd,
|
|
||||||
char16_t** targetStart, char16_t* targetEnd, ConversionFlags flags);
|
|
||||||
|
|
||||||
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
|
|
||||||
|
|
||||||
// #ifdef __cplusplus
|
|
||||||
// }
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
3370
3rdparty/linenoise-ng/src/linenoise.cpp
vendored
3370
3rdparty/linenoise-ng/src/linenoise.cpp
vendored
File diff suppressed because it is too large
Load Diff
315
3rdparty/linenoise-ng/src/wcwidth.cpp
vendored
315
3rdparty/linenoise-ng/src/wcwidth.cpp
vendored
@ -1,315 +0,0 @@
|
|||||||
/*
|
|
||||||
* This is an implementation of wcwidth() and wcswidth() (defined in
|
|
||||||
* IEEE Std 1002.1-2001) for Unicode.
|
|
||||||
*
|
|
||||||
* http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html
|
|
||||||
* http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html
|
|
||||||
*
|
|
||||||
* In fixed-width output devices, Latin characters all occupy a single
|
|
||||||
* "cell" position of equal width, whereas ideographic CJK characters
|
|
||||||
* occupy two such cells. Interoperability between terminal-line
|
|
||||||
* applications and (teletype-style) character terminals using the
|
|
||||||
* UTF-8 encoding requires agreement on which character should advance
|
|
||||||
* the cursor by how many cell positions. No established formal
|
|
||||||
* standards exist at present on which Unicode character shall occupy
|
|
||||||
* how many cell positions on character terminals. These routines are
|
|
||||||
* a first attempt of defining such behavior based on simple rules
|
|
||||||
* applied to data provided by the Unicode Consortium.
|
|
||||||
*
|
|
||||||
* For some graphical characters, the Unicode standard explicitly
|
|
||||||
* defines a character-cell width via the definition of the East Asian
|
|
||||||
* FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes.
|
|
||||||
* In all these cases, there is no ambiguity about which width a
|
|
||||||
* terminal shall use. For characters in the East Asian Ambiguous (A)
|
|
||||||
* class, the width choice depends purely on a preference of backward
|
|
||||||
* compatibility with either historic CJK or Western practice.
|
|
||||||
* Choosing single-width for these characters is easy to justify as
|
|
||||||
* the appropriate long-term solution, as the CJK practice of
|
|
||||||
* displaying these characters as double-width comes from historic
|
|
||||||
* implementation simplicity (8-bit encoded characters were displayed
|
|
||||||
* single-width and 16-bit ones double-width, even for Greek,
|
|
||||||
* Cyrillic, etc.) and not any typographic considerations.
|
|
||||||
*
|
|
||||||
* Much less clear is the choice of width for the Not East Asian
|
|
||||||
* (Neutral) class. Existing practice does not dictate a width for any
|
|
||||||
* of these characters. It would nevertheless make sense
|
|
||||||
* typographically to allocate two character cells to characters such
|
|
||||||
* as for instance EM SPACE or VOLUME INTEGRAL, which cannot be
|
|
||||||
* represented adequately with a single-width glyph. The following
|
|
||||||
* routines at present merely assign a single-cell width to all
|
|
||||||
* neutral characters, in the interest of simplicity. This is not
|
|
||||||
* entirely satisfactory and should be reconsidered before
|
|
||||||
* establishing a formal standard in this area. At the moment, the
|
|
||||||
* decision which Not East Asian (Neutral) characters should be
|
|
||||||
* represented by double-width glyphs cannot yet be answered by
|
|
||||||
* applying a simple rule from the Unicode database content. Setting
|
|
||||||
* up a proper standard for the behavior of UTF-8 character terminals
|
|
||||||
* will require a careful analysis not only of each Unicode character,
|
|
||||||
* but also of each presentation form, something the author of these
|
|
||||||
* routines has avoided to do so far.
|
|
||||||
*
|
|
||||||
* http://www.unicode.org/unicode/reports/tr11/
|
|
||||||
*
|
|
||||||
* Markus Kuhn -- 2007-05-26 (Unicode 5.0)
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software
|
|
||||||
* for any purpose and without fee is hereby granted. The author
|
|
||||||
* disclaims all warranties with regard to this software.
|
|
||||||
*
|
|
||||||
* Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <wchar.h>
|
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace linenoise_ng {
|
|
||||||
|
|
||||||
struct interval {
|
|
||||||
char32_t first;
|
|
||||||
char32_t last;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* auxiliary function for binary search in interval table */
|
|
||||||
static int bisearch(char32_t ucs, const struct interval *table, int max) {
|
|
||||||
int min = 0;
|
|
||||||
int mid;
|
|
||||||
|
|
||||||
if (ucs < table[0].first || ucs > table[max].last)
|
|
||||||
return 0;
|
|
||||||
while (max >= min) {
|
|
||||||
mid = (min + max) / 2;
|
|
||||||
if (ucs > table[mid].last)
|
|
||||||
min = mid + 1;
|
|
||||||
else if (ucs < table[mid].first)
|
|
||||||
max = mid - 1;
|
|
||||||
else
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* The following two functions define the column width of an ISO 10646
|
|
||||||
* character as follows:
|
|
||||||
*
|
|
||||||
* - The null character (U+0000) has a column width of 0.
|
|
||||||
*
|
|
||||||
* - Other C0/C1 control characters and DEL will lead to a return
|
|
||||||
* value of -1.
|
|
||||||
*
|
|
||||||
* - Non-spacing and enclosing combining characters (general
|
|
||||||
* category code Mn or Me in the Unicode database) have a
|
|
||||||
* column width of 0.
|
|
||||||
*
|
|
||||||
* - SOFT HYPHEN (U+00AD) has a column width of 1.
|
|
||||||
*
|
|
||||||
* - Other format characters (general category code Cf in the Unicode
|
|
||||||
* database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.
|
|
||||||
*
|
|
||||||
* - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)
|
|
||||||
* have a column width of 0.
|
|
||||||
*
|
|
||||||
* - Spacing characters in the East Asian Wide (W) or East Asian
|
|
||||||
* Full-width (F) category as defined in Unicode Technical
|
|
||||||
* Report #11 have a column width of 2.
|
|
||||||
*
|
|
||||||
* - All remaining characters (including all printable
|
|
||||||
* ISO 8859-1 and WGL4 characters, Unicode control characters,
|
|
||||||
* etc.) have a column width of 1.
|
|
||||||
*
|
|
||||||
* This implementation assumes that wchar_t characters are encoded
|
|
||||||
* in ISO 10646.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mk_wcwidth(char32_t ucs)
|
|
||||||
{
|
|
||||||
/* sorted list of non-overlapping intervals of non-spacing characters */
|
|
||||||
/* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */
|
|
||||||
static const struct interval combining[] = {
|
|
||||||
{ 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 },
|
|
||||||
{ 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
|
|
||||||
{ 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 },
|
|
||||||
{ 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 },
|
|
||||||
{ 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
|
|
||||||
{ 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
|
|
||||||
{ 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 },
|
|
||||||
{ 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D },
|
|
||||||
{ 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 },
|
|
||||||
{ 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD },
|
|
||||||
{ 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C },
|
|
||||||
{ 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D },
|
|
||||||
{ 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC },
|
|
||||||
{ 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD },
|
|
||||||
{ 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C },
|
|
||||||
{ 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D },
|
|
||||||
{ 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 },
|
|
||||||
{ 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 },
|
|
||||||
{ 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC },
|
|
||||||
{ 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
|
|
||||||
{ 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D },
|
|
||||||
{ 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 },
|
|
||||||
{ 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E },
|
|
||||||
{ 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC },
|
|
||||||
{ 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 },
|
|
||||||
{ 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E },
|
|
||||||
{ 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 },
|
|
||||||
{ 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 },
|
|
||||||
{ 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 },
|
|
||||||
{ 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F },
|
|
||||||
{ 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 },
|
|
||||||
{ 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD },
|
|
||||||
{ 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD },
|
|
||||||
{ 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 },
|
|
||||||
{ 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B },
|
|
||||||
{ 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 },
|
|
||||||
{ 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 },
|
|
||||||
{ 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF },
|
|
||||||
{ 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 },
|
|
||||||
{ 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F },
|
|
||||||
{ 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B },
|
|
||||||
{ 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F },
|
|
||||||
{ 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB },
|
|
||||||
{ 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
|
|
||||||
{ 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
|
|
||||||
{ 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
|
|
||||||
{ 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
|
|
||||||
{ 0xE0100, 0xE01EF }
|
|
||||||
};
|
|
||||||
|
|
||||||
/* test for 8-bit control characters */
|
|
||||||
if (ucs == 0)
|
|
||||||
return 0;
|
|
||||||
if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* binary search in table of non-spacing characters */
|
|
||||||
if (bisearch(ucs, combining,
|
|
||||||
sizeof(combining) / sizeof(struct interval) - 1))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* if we arrive here, ucs is not a combining or C0/C1 control character */
|
|
||||||
|
|
||||||
return 1 +
|
|
||||||
(ucs >= 0x1100 &&
|
|
||||||
(ucs <= 0x115f || /* Hangul Jamo init. consonants */
|
|
||||||
ucs == 0x2329 || ucs == 0x232a ||
|
|
||||||
(ucs >= 0x2e80 && ucs <= 0xa4cf &&
|
|
||||||
ucs != 0x303f) || /* CJK ... Yi */
|
|
||||||
(ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
|
|
||||||
(ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
|
|
||||||
(ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */
|
|
||||||
(ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
|
|
||||||
(ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */
|
|
||||||
(ucs >= 0xffe0 && ucs <= 0xffe6) ||
|
|
||||||
(ucs >= 0x20000 && ucs <= 0x2fffd) ||
|
|
||||||
(ucs >= 0x30000 && ucs <= 0x3fffd)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int mk_wcswidth(const char32_t* pwcs, size_t n)
|
|
||||||
{
|
|
||||||
int w, width = 0;
|
|
||||||
|
|
||||||
for (;*pwcs && n-- > 0; pwcs++)
|
|
||||||
if ((w = mk_wcwidth(*pwcs)) < 0)
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
width += w;
|
|
||||||
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The following functions are the same as mk_wcwidth() and
|
|
||||||
* mk_wcswidth(), except that spacing characters in the East Asian
|
|
||||||
* Ambiguous (A) category as defined in Unicode Technical Report #11
|
|
||||||
* have a column width of 2. This variant might be useful for users of
|
|
||||||
* CJK legacy encodings who want to migrate to UCS without changing
|
|
||||||
* the traditional terminal character-width behaviour. It is not
|
|
||||||
* otherwise recommended for general use.
|
|
||||||
*/
|
|
||||||
int mk_wcwidth_cjk(wchar_t ucs)
|
|
||||||
{
|
|
||||||
/* sorted list of non-overlapping intervals of East Asian Ambiguous
|
|
||||||
* characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
|
|
||||||
static const struct interval ambiguous[] = {
|
|
||||||
{ 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
|
|
||||||
{ 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 },
|
|
||||||
{ 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
|
|
||||||
{ 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
|
|
||||||
{ 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
|
|
||||||
{ 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
|
|
||||||
{ 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
|
|
||||||
{ 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
|
|
||||||
{ 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
|
|
||||||
{ 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
|
|
||||||
{ 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
|
|
||||||
{ 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
|
|
||||||
{ 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
|
|
||||||
{ 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
|
|
||||||
{ 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
|
|
||||||
{ 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB },
|
|
||||||
{ 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB },
|
|
||||||
{ 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 },
|
|
||||||
{ 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 },
|
|
||||||
{ 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 },
|
|
||||||
{ 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 },
|
|
||||||
{ 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 },
|
|
||||||
{ 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 },
|
|
||||||
{ 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 },
|
|
||||||
{ 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
|
|
||||||
{ 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
|
|
||||||
{ 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 },
|
|
||||||
{ 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 },
|
|
||||||
{ 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
|
|
||||||
{ 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 },
|
|
||||||
{ 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 },
|
|
||||||
{ 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B },
|
|
||||||
{ 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 },
|
|
||||||
{ 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 },
|
|
||||||
{ 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E },
|
|
||||||
{ 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 },
|
|
||||||
{ 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 },
|
|
||||||
{ 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F },
|
|
||||||
{ 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 },
|
|
||||||
{ 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF },
|
|
||||||
{ 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B },
|
|
||||||
{ 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 },
|
|
||||||
{ 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 },
|
|
||||||
{ 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 },
|
|
||||||
{ 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 },
|
|
||||||
{ 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 },
|
|
||||||
{ 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 },
|
|
||||||
{ 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 },
|
|
||||||
{ 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 },
|
|
||||||
{ 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F },
|
|
||||||
{ 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF },
|
|
||||||
{ 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD }
|
|
||||||
};
|
|
||||||
|
|
||||||
/* binary search in table of non-spacing characters */
|
|
||||||
if (bisearch(ucs, ambiguous,
|
|
||||||
sizeof(ambiguous) / sizeof(struct interval) - 1))
|
|
||||||
return 2;
|
|
||||||
|
|
||||||
return mk_wcwidth(ucs);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n)
|
|
||||||
{
|
|
||||||
int w, width = 0;
|
|
||||||
|
|
||||||
for (;*pwcs && n-- > 0; pwcs++)
|
|
||||||
if ((w = mk_wcwidth_cjk(*pwcs)) < 0)
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
width += w;
|
|
||||||
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
68
3rdparty/linenoise-ng/tst/example.c
vendored
68
3rdparty/linenoise-ng/tst/example.c
vendored
@ -1,68 +0,0 @@
|
|||||||
#include "linenoise.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
static const char* examples[] = {
|
|
||||||
"db", "hello", "hallo", "hans", "hansekogge", "seamann", "quetzalcoatl", "quit", "power", NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
void completionHook (char const* prefix, linenoiseCompletions* lc) {
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; examples[i] != NULL; ++i) {
|
|
||||||
if (strncmp(prefix, examples[i], strlen(prefix)) == 0) {
|
|
||||||
linenoiseAddCompletion(lc, examples[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main (int argc, char** argv) {
|
|
||||||
linenoiseInstallWindowChangeHandler();
|
|
||||||
|
|
||||||
while(argc > 1) {
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
if (!strcmp(*argv, "--keycodes")) {
|
|
||||||
linenoisePrintKeyCodes();
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* file = "./history";
|
|
||||||
|
|
||||||
linenoiseHistoryLoad(file);
|
|
||||||
linenoiseSetCompletionCallback(completionHook);
|
|
||||||
|
|
||||||
printf("starting...\n");
|
|
||||||
|
|
||||||
char const* prompt = "\x1b[1;32mlinenoise\x1b[0m> ";
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
char* result = linenoise(prompt);
|
|
||||||
|
|
||||||
if (result == NULL) {
|
|
||||||
break;
|
|
||||||
} else if (!strncmp(result, "/history", 8)) {
|
|
||||||
/* Display the current history. */
|
|
||||||
for (int index = 0; ; ++index) {
|
|
||||||
char* hist = linenoiseHistoryLine(index);
|
|
||||||
if (hist == NULL) break;
|
|
||||||
printf("%4d: %s\n", index, hist);
|
|
||||||
free(hist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (*result == '\0') {
|
|
||||||
free(result);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("thanks for the input.\n");
|
|
||||||
linenoiseHistoryAdd(result);
|
|
||||||
free(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
linenoiseHistorySave(file);
|
|
||||||
linenoiseHistoryFree();
|
|
||||||
}
|
|
13
3rdparty/linenoise/Makefile
vendored
Normal file
13
3rdparty/linenoise/Makefile
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
all: linenoise_example linenoise_utf8_example linenoise_cpp_example
|
||||||
|
|
||||||
|
linenoise_example: linenoise.h linenoise.c example.c
|
||||||
|
$(CC) -Wall -W -Os -g -o $@ linenoise.c example.c
|
||||||
|
|
||||||
|
linenoise_utf8_example: linenoise.c utf8.c example.c
|
||||||
|
$(CC) -DNO_COMPLETION -DUSE_UTF8 -Wall -W -Os -g -o $@ linenoise.c utf8.c example.c
|
||||||
|
|
||||||
|
linenoise_cpp_example: linenoise.h linenoise.c
|
||||||
|
g++ -Wall -W -Os -g -o $@ linenoise.c example.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f linenoise_example linenoise_utf8_example linenoise_cpp_example *.o
|
47
3rdparty/linenoise/README.markdown
vendored
Normal file
47
3rdparty/linenoise/README.markdown
vendored
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# Linenoise
|
||||||
|
|
||||||
|
A minimal, zero-config, BSD licensed, readline replacement.
|
||||||
|
|
||||||
|
News: linenoise now includes minimal completion support, thanks to Pieter Noordhuis (@pnoordhuis).
|
||||||
|
|
||||||
|
News: linenoise is now part of [Android](http://android.git.kernel.org/?p=platform/system/core.git;a=tree;f=liblinenoise;h=56450eaed7f783760e5e6a5993ef75cde2e29dea;hb=HEAD Android)!
|
||||||
|
|
||||||
|
## Can a line editing library be 20k lines of code?
|
||||||
|
|
||||||
|
Line editing with some support for history is a really important feature for command line utilities. Instead of retyping almost the same stuff again and again it's just much better to hit the up arrow and edit on syntax errors, or in order to try a slightly different command. But apparently code dealing with terminals is some sort of Black Magic: readline is 30k lines of code, libedit 20k. Is it reasonable to link small utilities to huge libraries just to get a minimal support for line editing?
|
||||||
|
|
||||||
|
So what usually happens is either:
|
||||||
|
|
||||||
|
* Large programs with configure scripts disabling line editing if readline is not present in the system, or not supporting it at all since readline is GPL licensed and libedit (the BSD clone) is not as known and available as readline is (Real world example of this problem: Tclsh).
|
||||||
|
* Smaller programs not using a configure script not supporting line editing at all (A problem we had with Redis-cli for instance).
|
||||||
|
|
||||||
|
The result is a pollution of binaries without line editing support.
|
||||||
|
|
||||||
|
So I spent more or less two hours doing a reality check resulting in this little library: is it *really* needed for a line editing library to be 20k lines of code? Apparently not, it is possibe to get a very small, zero configuration, trivial to embed library, that solves the problem. Smaller programs will just include this, supporing line editing out of the box. Larger programs may use this little library or just checking with configure if readline/libedit is available and resorting to linenoise if not.
|
||||||
|
|
||||||
|
## Terminals, in 2010.
|
||||||
|
|
||||||
|
Apparently almost every terminal you can happen to use today has some kind of support for VT100 alike escape sequences. So I tried to write a lib using just very basic VT100 features. The resulting library appears to work everywhere I tried to use it.
|
||||||
|
|
||||||
|
Since it's so young I guess there are a few bugs, or the lib may not compile or work with some operating system, but it's a matter of a few weeks and eventually we'll get it right, and there will be no excuses for not shipping command line tools without built-in line editing support.
|
||||||
|
|
||||||
|
The library is currently less than 2000 lines of code. In order to use it in your project just look at the *example.c* file in the source distribution, it is trivial. Linenoise is BSD code, so you can use both in free software and commercial software.
|
||||||
|
|
||||||
|
## Tested with...
|
||||||
|
|
||||||
|
* Linux text only console ($TERM = linux)
|
||||||
|
* Linux KDE terminal application ($TERM = xterm)
|
||||||
|
* Linux xterm ($TERM = xterm)
|
||||||
|
* Mac OS X iTerm ($TERM = xterm)
|
||||||
|
* Mac OS X default Terminal.app ($TERM = xterm)
|
||||||
|
* OpenBSD 4.5 through an OSX Terminal.app ($TERM = screen)
|
||||||
|
* IBM AIX 6.1
|
||||||
|
* FreeBSD xterm ($TERM = xterm)
|
||||||
|
|
||||||
|
Please test it everywhere you can and report back!
|
||||||
|
|
||||||
|
## Let's push this forward!
|
||||||
|
|
||||||
|
Please fork it and add something interesting and send me a pull request. What's especially interesting are fixes, new key bindings, completion.
|
||||||
|
|
||||||
|
Send feedbacks to antirez at gmail
|
67
3rdparty/linenoise/example.c
vendored
Normal file
67
3rdparty/linenoise/example.c
vendored
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "linenoise.h"
|
||||||
|
|
||||||
|
#ifndef NO_COMPLETION
|
||||||
|
void completion(const char *buf, linenoiseCompletions *lc, void *userdata) {
|
||||||
|
if (buf[0] == 'h') {
|
||||||
|
linenoiseAddCompletion(lc,"hello");
|
||||||
|
linenoiseAddCompletion(lc,"hello there");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
char *line;
|
||||||
|
#ifdef HAVE_MULTILINE
|
||||||
|
/* Note: multiline support has not yet been integrated */
|
||||||
|
char *prgname = argv[0];
|
||||||
|
|
||||||
|
/* Parse options, with --multiline we enable multi line editing. */
|
||||||
|
while(argc > 1) {
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
if (!strcmp(*argv,"--multiline")) {
|
||||||
|
linenoiseSetMultiLine(1);
|
||||||
|
printf("Multi-line mode enabled.\n");
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Usage: %s [--multiline]\n", prgname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NO_COMPLETION
|
||||||
|
/* Set the completion callback. This will be called every time the
|
||||||
|
* user uses the <tab> key. */
|
||||||
|
linenoiseSetCompletionCallback(completion, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Load history from file. The history file is just a plain text file
|
||||||
|
* where entries are separated by newlines. */
|
||||||
|
linenoiseHistoryLoad("history.txt"); /* Load the history at startup */
|
||||||
|
|
||||||
|
/* Now this is the main loop of the typical linenoise-based application.
|
||||||
|
* The call to linenoise() will block as long as the user types something
|
||||||
|
* and presses enter.
|
||||||
|
*
|
||||||
|
* The typed string is returned as a malloc() allocated string by
|
||||||
|
* linenoise, so the user needs to free() it. */
|
||||||
|
while((line = linenoise("hello> ")) != NULL) {
|
||||||
|
/* Do something with the string. */
|
||||||
|
if (line[0] != '\0' && line[0] != '/') {
|
||||||
|
printf("echo: '%s'\n", line);
|
||||||
|
linenoiseHistoryAdd(line); /* Add to the history. */
|
||||||
|
linenoiseHistorySave("history.txt"); /* Save the history on disk. */
|
||||||
|
} else if (!strncmp(line,"/historylen",11)) {
|
||||||
|
/* The "/historylen" command will change the history len. */
|
||||||
|
int len = atoi(line+11);
|
||||||
|
linenoiseHistorySetMaxLen(len);
|
||||||
|
} else if (line[0] == '/') {
|
||||||
|
printf("Unreconized command: %s\n", line);
|
||||||
|
}
|
||||||
|
free(line);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
1765
3rdparty/linenoise/linenoise.c
vendored
Normal file
1765
3rdparty/linenoise/linenoise.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
128
3rdparty/linenoise/linenoise.h
vendored
Normal file
128
3rdparty/linenoise/linenoise.h
vendored
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/* linenoise.h -- guerrilla line editing library against the idea that a
|
||||||
|
* line editing lib needs to be 20,000 lines of C code.
|
||||||
|
*
|
||||||
|
* See linenoise.c for more information.
|
||||||
|
*
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||||
|
* Copyright (c) 2010, Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __LINENOISE_H
|
||||||
|
#define __LINENOISE_H
|
||||||
|
|
||||||
|
#ifndef NO_COMPLETION
|
||||||
|
typedef struct linenoiseCompletions {
|
||||||
|
size_t len;
|
||||||
|
char **cvec;
|
||||||
|
int pos;
|
||||||
|
} linenoiseCompletions;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The callback type for tab completion handlers.
|
||||||
|
*/
|
||||||
|
typedef void(linenoiseCompletionCallback)(const char *prefix, linenoiseCompletions *comp, int pos);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets the current tab completion handler and returns the previous one, or NULL
|
||||||
|
* if no prior one has been set.
|
||||||
|
*/
|
||||||
|
linenoiseCompletionCallback * linenoiseSetCompletionCallback(linenoiseCompletionCallback *comp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adds a copy of the given string to the given completion list. The copy is owned
|
||||||
|
* by the linenoiseCompletions object.
|
||||||
|
*/
|
||||||
|
void linenoiseAddCompletion(linenoiseCompletions *comp, const char *str, int pos);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prompts for input using the given string as the input
|
||||||
|
* prompt. Returns when the user has tapped ENTER or (on an empty
|
||||||
|
* line) EOF (Ctrl-D on Unix, Ctrl-Z on Windows). Returns either
|
||||||
|
* a copy of the entered string (for ENTER) or NULL (on EOF). The
|
||||||
|
* caller owns the returned string and must eventually free() it.
|
||||||
|
*/
|
||||||
|
char *linenoise(const char *prompt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the screen.
|
||||||
|
*/
|
||||||
|
void linenoiseClearScreen(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adds a copy of the given line of the command history.
|
||||||
|
*/
|
||||||
|
int linenoiseHistoryAdd(const char *line);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets the maximum length of the command history, in lines.
|
||||||
|
* If the history is currently longer, it will be trimmed,
|
||||||
|
* retaining only the most recent entries. If len is 0 or less
|
||||||
|
* then this function does nothing.
|
||||||
|
*/
|
||||||
|
int linenoiseHistorySetMaxLen(int len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the current maximum length of the history, in lines.
|
||||||
|
*/
|
||||||
|
int linenoiseHistoryGetMaxLen(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Saves the current contents of the history to the given file.
|
||||||
|
* Returns 0 on success.
|
||||||
|
*/
|
||||||
|
int linenoiseHistorySave(const char *filename);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Replaces the current history with the contents
|
||||||
|
* of the given file. Returns 0 on success.
|
||||||
|
*/
|
||||||
|
int linenoiseHistoryLoad(const char *filename);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Frees all history entries, clearing the history.
|
||||||
|
*/
|
||||||
|
void linenoiseHistoryFree(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a pointer to the list of history entries, writing its
|
||||||
|
* length to *len if len is not NULL. The memory is owned by linenoise
|
||||||
|
* and must not be freed.
|
||||||
|
*/
|
||||||
|
char **linenoiseHistory(int *len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the number of display columns in the current terminal.
|
||||||
|
*/
|
||||||
|
int linenoiseColumns(void);
|
||||||
|
|
||||||
|
void linenoisePreloadBuffer(const char* preloadText);
|
||||||
|
|
||||||
|
#endif /* __LINENOISE_H */
|
227
3rdparty/linenoise/utf8.c
vendored
Normal file
227
3rdparty/linenoise/utf8.c
vendored
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
/**
|
||||||
|
* UTF-8 utility functions
|
||||||
|
*
|
||||||
|
* (c) 2010-2016 Steve Bennett <steveb@workware.net.au>
|
||||||
|
*
|
||||||
|
* See LICENCE for licence details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
|
#ifdef USE_UTF8
|
||||||
|
int utf8_fromunicode(char *p, unsigned uc)
|
||||||
|
{
|
||||||
|
if (uc <= 0x7f) {
|
||||||
|
*p = uc;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (uc <= 0x7ff) {
|
||||||
|
*p++ = 0xc0 | ((uc & 0x7c0) >> 6);
|
||||||
|
*p = 0x80 | (uc & 0x3f);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else if (uc <= 0xffff) {
|
||||||
|
*p++ = 0xe0 | ((uc & 0xf000) >> 12);
|
||||||
|
*p++ = 0x80 | ((uc & 0xfc0) >> 6);
|
||||||
|
*p = 0x80 | (uc & 0x3f);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
/* Note: We silently truncate to 21 bits here: 0x1fffff */
|
||||||
|
else {
|
||||||
|
*p++ = 0xf0 | ((uc & 0x1c0000) >> 18);
|
||||||
|
*p++ = 0x80 | ((uc & 0x3f000) >> 12);
|
||||||
|
*p++ = 0x80 | ((uc & 0xfc0) >> 6);
|
||||||
|
*p = 0x80 | (uc & 0x3f);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int utf8_charlen(int c)
|
||||||
|
{
|
||||||
|
if ((c & 0x80) == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ((c & 0xe0) == 0xc0) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if ((c & 0xf0) == 0xe0) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
if ((c & 0xf8) == 0xf0) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
/* Invalid sequence */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int utf8_strlen(const char *str, int bytelen)
|
||||||
|
{
|
||||||
|
int charlen = 0;
|
||||||
|
if (bytelen < 0) {
|
||||||
|
bytelen = strlen(str);
|
||||||
|
}
|
||||||
|
while (bytelen) {
|
||||||
|
int c;
|
||||||
|
int l = utf8_tounicode(str, &c);
|
||||||
|
charlen++;
|
||||||
|
str += l;
|
||||||
|
bytelen -= l;
|
||||||
|
}
|
||||||
|
return charlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int utf8_strwidth(const char *str, int charlen)
|
||||||
|
{
|
||||||
|
int width = 0;
|
||||||
|
while (charlen) {
|
||||||
|
int c;
|
||||||
|
int l = utf8_tounicode(str, &c);
|
||||||
|
width += utf8_width(c);
|
||||||
|
str += l;
|
||||||
|
charlen--;
|
||||||
|
}
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int utf8_index(const char *str, int index)
|
||||||
|
{
|
||||||
|
const char *s = str;
|
||||||
|
while (index--) {
|
||||||
|
int c;
|
||||||
|
s += utf8_tounicode(s, &c);
|
||||||
|
}
|
||||||
|
return s - str;
|
||||||
|
}
|
||||||
|
|
||||||
|
int utf8_tounicode(const char *str, int *uc)
|
||||||
|
{
|
||||||
|
unsigned const char *s = (unsigned const char *)str;
|
||||||
|
|
||||||
|
if (s[0] < 0xc0) {
|
||||||
|
*uc = s[0];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (s[0] < 0xe0) {
|
||||||
|
if ((s[1] & 0xc0) == 0x80) {
|
||||||
|
*uc = ((s[0] & ~0xc0) << 6) | (s[1] & ~0x80);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (s[0] < 0xf0) {
|
||||||
|
if (((str[1] & 0xc0) == 0x80) && ((str[2] & 0xc0) == 0x80)) {
|
||||||
|
*uc = ((s[0] & ~0xe0) << 12) | ((s[1] & ~0x80) << 6) | (s[2] & ~0x80);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (s[0] < 0xf8) {
|
||||||
|
if (((str[1] & 0xc0) == 0x80) && ((str[2] & 0xc0) == 0x80) && ((str[3] & 0xc0) == 0x80)) {
|
||||||
|
*uc = ((s[0] & ~0xf0) << 18) | ((s[1] & ~0x80) << 12) | ((s[2] & ~0x80) << 6) | (s[3] & ~0x80);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Invalid sequence, so just return the byte */
|
||||||
|
*uc = *s;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct utf8range {
|
||||||
|
int lower; /* lower inclusive */
|
||||||
|
int upper; /* upper exclusive */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* From http://unicode.org/Public/UNIDATA/UnicodeData.txt */
|
||||||
|
static const struct utf8range unicode_range_combining[] = {
|
||||||
|
{ 0x0300, 0x0370 }, { 0x0483, 0x048a }, { 0x0591, 0x05be }, { 0x05bf, 0x05c0 },
|
||||||
|
{ 0x05c1, 0x05c3 }, { 0x05c4, 0x05c6 }, { 0x05c7, 0x05d0 }, { 0x0610, 0x061b },
|
||||||
|
{ 0x064b, 0x0660 }, { 0x0670, 0x0671 }, { 0x06d6, 0x06dd }, { 0x06de, 0x06e5 },
|
||||||
|
{ 0x06e7, 0x06e9 }, { 0x06ea, 0x06ee }, { 0x0711, 0x0712 }, { 0x0730, 0x074d },
|
||||||
|
{ 0x07a6, 0x07b1 }, { 0x07eb, 0x07f4 }, { 0x0816, 0x081a }, { 0x081b, 0x0824 },
|
||||||
|
{ 0x0825, 0x0828 }, { 0x0829, 0x0830 }, { 0x0900, 0x0904 }, { 0x093c, 0x093d },
|
||||||
|
{ 0x093e, 0x0950 }, { 0x0951, 0x0958 }, { 0x0962, 0x0964 }, { 0x0981, 0x0985 },
|
||||||
|
{ 0x09bc, 0x09bd }, { 0x09be, 0x09ce }, { 0x09d7, 0x09dc }, { 0x09e2, 0x09e6 },
|
||||||
|
{ 0x0a01, 0x0a05 }, { 0x0a3c, 0x0a59 }, { 0x0a70, 0x0a72 }, { 0x0a75, 0x0a85 },
|
||||||
|
{ 0x0abc, 0x0abd }, { 0x0abe, 0x0ad0 }, { 0x0ae2, 0x0ae6 }, { 0x0b01, 0x0b05 },
|
||||||
|
{ 0x0b3c, 0x0b3d }, { 0x0b3e, 0x0b5c }, { 0x0b62, 0x0b66 }, { 0x0b82, 0x0b83 },
|
||||||
|
{ 0x0bbe, 0x0bd0 }, { 0x0bd7, 0x0be6 }, { 0x0c01, 0x0c05 }, { 0x0c3e, 0x0c58 },
|
||||||
|
{ 0x0c62, 0x0c66 }, { 0x0c82, 0x0c85 }, { 0x0cbc, 0x0cbd }, { 0x0cbe, 0x0cde },
|
||||||
|
{ 0x0ce2, 0x0ce6 }, { 0x0d02, 0x0d05 }, { 0x0d3e, 0x0d60 }, { 0x0d62, 0x0d66 },
|
||||||
|
{ 0x0d82, 0x0d85 }, { 0x0dca, 0x0df4 }, { 0x0e31, 0x0e32 }, { 0x0e34, 0x0e3f },
|
||||||
|
{ 0x0e47, 0x0e4f }, { 0x0eb1, 0x0eb2 }, { 0x0eb4, 0x0ebd }, { 0x0ec8, 0x0ed0 },
|
||||||
|
{ 0x0f18, 0x0f1a }, { 0x0f35, 0x0f36 }, { 0x0f37, 0x0f38 }, { 0x0f39, 0x0f3a },
|
||||||
|
{ 0x0f3e, 0x0f40 }, { 0x0f71, 0x0f85 }, { 0x0f86, 0x0f88 }, { 0x0f90, 0x0fbe },
|
||||||
|
{ 0x0fc6, 0x0fc7 }, { 0x102b, 0x103f }, { 0x1056, 0x105a }, { 0x105e, 0x1061 },
|
||||||
|
{ 0x1062, 0x1065 }, { 0x1067, 0x106e }, { 0x1071, 0x1075 }, { 0x1082, 0x108e },
|
||||||
|
{ 0x108f, 0x1090 }, { 0x109a, 0x109e }, { 0x135f, 0x1360 }, { 0x1712, 0x1720 },
|
||||||
|
{ 0x1732, 0x1735 }, { 0x1752, 0x1760 }, { 0x1772, 0x1780 }, { 0x17b6, 0x17d4 },
|
||||||
|
{ 0x17dd, 0x17e0 }, { 0x180b, 0x180e }, { 0x18a9, 0x18aa }, { 0x1920, 0x1940 },
|
||||||
|
{ 0x19b0, 0x19c1 }, { 0x19c8, 0x19d0 }, { 0x1a17, 0x1a1e }, { 0x1a55, 0x1a80 },
|
||||||
|
{ 0x1b00, 0x1b05 }, { 0x1b34, 0x1b45 }, { 0x1b6b, 0x1b74 }, { 0x1b80, 0x1b83 },
|
||||||
|
{ 0x1ba1, 0x1bae }, { 0x1c24, 0x1c3b }, { 0x1cd0, 0x1cd3 }, { 0x1cd4, 0x1ce9 },
|
||||||
|
{ 0x1ced, 0x1cee }, { 0x1cf2, 0x1d00 }, { 0x1dc0, 0x1e00 }, { 0x20d0, 0x2100 },
|
||||||
|
{ 0x2cef, 0x2cf9 }, { 0x2de0, 0x2e00 }, { 0x302a, 0x3030 }, { 0x3099, 0x309b },
|
||||||
|
{ 0xa66f, 0xa673 }, { 0xa67c, 0xa67e }, { 0xa6f0, 0xa6f2 }, { 0xa802, 0xa803 },
|
||||||
|
{ 0xa806, 0xa807 }, { 0xa80b, 0xa80c }, { 0xa823, 0xa828 }, { 0xa880, 0xa882 },
|
||||||
|
{ 0xa8b4, 0xa8ce }, { 0xa8e0, 0xa8f2 }, { 0xa926, 0xa92e }, { 0xa947, 0xa95f },
|
||||||
|
{ 0xa980, 0xa984 }, { 0xa9b3, 0xa9c1 }, { 0xaa29, 0xaa40 }, { 0xaa43, 0xaa44 },
|
||||||
|
{ 0xaa4c, 0xaa50 }, { 0xaa7b, 0xaa80 }, { 0xaab0, 0xaab1 }, { 0xaab2, 0xaab5 },
|
||||||
|
{ 0xaab7, 0xaab9 }, { 0xaabe, 0xaac0 }, { 0xaac1, 0xaac2 }, { 0xabe3, 0xabeb },
|
||||||
|
{ 0xabec, 0xabf0 }, { 0xfb1e, 0xfb1f }, { 0xfe00, 0xfe10 }, { 0xfe20, 0xfe30 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct utf8range unicode_range_wide[] = {
|
||||||
|
{ 0x1100, 0x115f }, { 0x2329, 0x232a }, { 0x2e80, 0x2e99 }, { 0x2e9b, 0x2ef3 },
|
||||||
|
{ 0x2f00, 0x2fd5 }, { 0x2ff0, 0x2ffb }, { 0x3000, 0x303e }, { 0x3041, 0x3096 },
|
||||||
|
{ 0x3099, 0x30ff }, { 0x3105, 0x312d }, { 0x3131, 0x318e }, { 0x3190, 0x31ba },
|
||||||
|
{ 0x31c0, 0x31e3 }, { 0x31f0, 0x321e }, { 0x3220, 0x3247 }, { 0x3250, 0x4dbf },
|
||||||
|
{ 0x4e00, 0xa48c }, { 0xa490, 0xa4c6 }, { 0xa960, 0xa97c }, { 0xac00, 0xd7a3 },
|
||||||
|
{ 0xf900, 0xfaff }, { 0xfe10, 0xfe19 }, { 0xfe30, 0xfe52 }, { 0xfe54, 0xfe66 },
|
||||||
|
{ 0xfe68, 0xfe6b }, { 0xff01, 0xffe6 }, { 0x1b000, 0x1b001 }, { 0x1f200, 0x1f202 },
|
||||||
|
{ 0x1f210, 0x1f23a }, { 0x1f240, 0x1f248 }, { 0x1f250, 0x1f251 }, { 0x20000, 0x3fffd },
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ARRAYSIZE(A) sizeof(A) / sizeof(*(A))
|
||||||
|
|
||||||
|
static int cmp_range(const void *key, const void *cm)
|
||||||
|
{
|
||||||
|
const struct utf8range *range = (const struct utf8range *)cm;
|
||||||
|
int ch = *(int *)key;
|
||||||
|
if (ch < range->lower) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ch >= range->upper) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int utf8_in_range(const struct utf8range *range, int num, int ch)
|
||||||
|
{
|
||||||
|
const struct utf8range *r =
|
||||||
|
bsearch(&ch, range, num, sizeof(*range), cmp_range);
|
||||||
|
|
||||||
|
if (r) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int utf8_width(int ch)
|
||||||
|
{
|
||||||
|
/* short circuit for common case */
|
||||||
|
if (isascii(ch)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (utf8_in_range(unicode_range_combining, ARRAYSIZE(unicode_range_combining), ch)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (utf8_in_range(unicode_range_wide, ARRAYSIZE(unicode_range_wide), ch)) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
103
3rdparty/linenoise/utf8.h
vendored
Normal file
103
3rdparty/linenoise/utf8.h
vendored
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#ifndef UTF8_UTIL_H
|
||||||
|
#define UTF8_UTIL_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UTF-8 utility functions
|
||||||
|
*
|
||||||
|
* (c) 2010-2016 Steve Bennett <steveb@workware.net.au>
|
||||||
|
*
|
||||||
|
* See LICENCE for licence details.
|
||||||
|
*/
|
||||||
|
#define USE_UTF8
|
||||||
|
|
||||||
|
#ifndef USE_UTF8
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
/* No utf-8 support. 1 byte = 1 char */
|
||||||
|
#define utf8_strlen(S, B) ((B) < 0 ? (int)strlen(S) : (B))
|
||||||
|
#define utf8_strwidth(S, B) utf8_strlen((S), (B))
|
||||||
|
#define utf8_tounicode(S, CP) (*(CP) = (unsigned char)*(S), 1)
|
||||||
|
#define utf8_index(C, I) (I)
|
||||||
|
#define utf8_charlen(C) 1
|
||||||
|
#define utf8_width(C) 1
|
||||||
|
|
||||||
|
#else
|
||||||
|
/**
|
||||||
|
* Converts the given unicode codepoint (0 - 0x1fffff) to utf-8
|
||||||
|
* and stores the result at 'p'.
|
||||||
|
*
|
||||||
|
* Returns the number of utf-8 characters
|
||||||
|
*/
|
||||||
|
int utf8_fromunicode(char *p, unsigned uc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the length of the utf-8 sequence starting with 'c'.
|
||||||
|
*
|
||||||
|
* Returns 1-4, or -1 if this is not a valid start byte.
|
||||||
|
*
|
||||||
|
* Note that charlen=4 is not supported by the rest of the API.
|
||||||
|
*/
|
||||||
|
int utf8_charlen(int c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of characters in the utf-8
|
||||||
|
* string of the given byte length.
|
||||||
|
*
|
||||||
|
* Any bytes which are not part of an valid utf-8
|
||||||
|
* sequence are treated as individual characters.
|
||||||
|
*
|
||||||
|
* The string *must* be null terminated.
|
||||||
|
*
|
||||||
|
* Does not support unicode code points > \u1fffff
|
||||||
|
*/
|
||||||
|
int utf8_strlen(const char *str, int bytelen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the display width of the first 'charlen' characters in 'str'.
|
||||||
|
* See utf8_width()
|
||||||
|
*/
|
||||||
|
int utf8_strwidth(const char *str, int charlen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the byte index of the given character in the utf-8 string.
|
||||||
|
*
|
||||||
|
* The string *must* be null terminated.
|
||||||
|
*
|
||||||
|
* This will return the byte length of a utf-8 string
|
||||||
|
* if given the char length.
|
||||||
|
*/
|
||||||
|
int utf8_index(const char *str, int charindex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the unicode codepoint corresponding to the
|
||||||
|
* utf-8 sequence 'str'.
|
||||||
|
*
|
||||||
|
* Stores the result in *uc and returns the number of bytes
|
||||||
|
* consumed.
|
||||||
|
*
|
||||||
|
* If 'str' is null terminated, then an invalid utf-8 sequence
|
||||||
|
* at the end of the string will be returned as individual bytes.
|
||||||
|
*
|
||||||
|
* If it is not null terminated, the length *must* be checked first.
|
||||||
|
*
|
||||||
|
* Does not support unicode code points > \u1fffff
|
||||||
|
*/
|
||||||
|
int utf8_tounicode(const char *str, int *uc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the width (in characters) of the given unicode codepoint.
|
||||||
|
* This is 1 for normal letters and 0 for combining characters and 2 for wide characters.
|
||||||
|
*/
|
||||||
|
int utf8_width(int ch);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
8
3rdparty/lua-linenoise/linenoise.c
vendored
8
3rdparty/lua-linenoise/linenoise.c
vendored
@ -44,7 +44,7 @@ static int handle_ln_ok(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void completion_callback_wrapper(const char *line, linenoiseCompletions *completions)
|
static void completion_callback_wrapper(const char *line, linenoiseCompletions *completions, int pos)
|
||||||
{
|
{
|
||||||
lua_State *L = completion_state;
|
lua_State *L = completion_state;
|
||||||
|
|
||||||
@ -54,8 +54,9 @@ static void completion_callback_wrapper(const char *line, linenoiseCompletions *
|
|||||||
lua_setmetatable(L, -2);
|
lua_setmetatable(L, -2);
|
||||||
|
|
||||||
lua_pushstring(L, line);
|
lua_pushstring(L, line);
|
||||||
|
lua_pushinteger(L, pos);
|
||||||
|
|
||||||
lua_pcall(L, 2, 0, 0);
|
lua_pcall(L, 3, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_linenoise(lua_State *L)
|
static int l_linenoise(lua_State *L)
|
||||||
@ -161,8 +162,9 @@ static int l_addcompletion(lua_State *L)
|
|||||||
{
|
{
|
||||||
linenoiseCompletions *completions = *((linenoiseCompletions **) luaL_checkudata(L, 1, LN_COMPLETION_TYPE));
|
linenoiseCompletions *completions = *((linenoiseCompletions **) luaL_checkudata(L, 1, LN_COMPLETION_TYPE));
|
||||||
const char *entry = luaL_checkstring(L, 2);
|
const char *entry = luaL_checkstring(L, 2);
|
||||||
|
int pos = luaL_checkinteger(L, 3);
|
||||||
|
|
||||||
linenoiseAddCompletion(completions, (char *) entry);
|
linenoiseAddCompletion(completions, (char *) entry, pos);
|
||||||
|
|
||||||
return handle_ln_ok(L);
|
return handle_ln_ok(L);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
-- license:BSD-3-Clause
|
-- license:MIT
|
||||||
-- copyright-holders:Carl
|
-- copyright-holders:Carl, Patrick Rapin, Reuben Thomas
|
||||||
|
-- completion from https://github.com/rrthomas/lua-rlcompleter
|
||||||
local exports = {}
|
local exports = {}
|
||||||
exports.name = "console"
|
exports.name = "console"
|
||||||
exports.version = "0.0.1"
|
exports.version = "0.0.1"
|
||||||
@ -14,6 +15,7 @@ function console.startplugin()
|
|||||||
local started = false
|
local started = false
|
||||||
local ln = require("linenoise")
|
local ln = require("linenoise")
|
||||||
local preload = false
|
local preload = false
|
||||||
|
local matches = {}
|
||||||
print(" _/ _/ _/_/ _/ _/ _/_/_/_/");
|
print(" _/ _/ _/_/ _/ _/ _/_/_/_/");
|
||||||
print(" _/_/ _/_/ _/ _/ _/_/ _/_/ _/ ");
|
print(" _/_/ _/_/ _/ _/ _/_/ _/_/ _/ ");
|
||||||
print(" _/ _/ _/ _/_/_/_/ _/ _/ _/ _/_/_/ ");
|
print(" _/ _/ _/ _/_/_/_/ _/ _/ _/ _/_/_/ ");
|
||||||
@ -27,13 +29,80 @@ function console.startplugin()
|
|||||||
ln.historysetmaxlen(10)
|
ln.historysetmaxlen(10)
|
||||||
local scr = [[
|
local scr = [[
|
||||||
local ln = require('linenoise')
|
local ln = require('linenoise')
|
||||||
ln.setcompletion(function(c, str)
|
ln.setcompletion(function(c, str, pos)
|
||||||
status = str
|
status = str .. "\x01" .. tostring(pos)
|
||||||
yield()
|
yield()
|
||||||
status:gsub('[^,]*', function(s) if s ~= '' then ln.addcompletion(c, s) end end)
|
ln.addcompletion(c, status:match("([^\x01]*)\x01(.*)"))
|
||||||
end)
|
end)
|
||||||
return ln.linenoise('\x1b[1;36m[MAME]\x1b[0m> ')
|
return ln.linenoise('\x1b[1;36m[MAME]\x1b[0m> ')
|
||||||
]]
|
]]
|
||||||
|
local keywords = {
|
||||||
|
'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for',
|
||||||
|
'function', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat',
|
||||||
|
'return', 'then', 'true', 'until', 'while'
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Main completion function. It evaluates the current sub-expression
|
||||||
|
-- to determine its type. Currently supports tables fields, global
|
||||||
|
-- variables and function prototype completion.
|
||||||
|
local function contextual_list(expr, sep, str, word)
|
||||||
|
local function add(value)
|
||||||
|
value = tostring(value)
|
||||||
|
if value:match("^" .. word) then
|
||||||
|
matches[#matches + 1] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- This function is called in a context where a keyword or a global
|
||||||
|
-- variable can be inserted. Local variables cannot be listed!
|
||||||
|
local function add_globals()
|
||||||
|
for _, k in ipairs(keywords) do
|
||||||
|
add(k)
|
||||||
|
end
|
||||||
|
for k in pairs(_G) do
|
||||||
|
add(k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if expr and expr ~= "" then
|
||||||
|
local v = loadstring("return " .. expr)
|
||||||
|
if v then
|
||||||
|
err, v = pcall(v)
|
||||||
|
if (not err) or (not v) then
|
||||||
|
add_globals()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local t = type(v)
|
||||||
|
if sep == '.' or sep == ':' then
|
||||||
|
if t == 'table' then
|
||||||
|
for k, v in pairs(v) do
|
||||||
|
if type(k) == 'string' and (sep ~= ':' or type(v) == "function") then
|
||||||
|
add(k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif t == 'userdata' then
|
||||||
|
for k, v in pairs(getmetatable(v)) do
|
||||||
|
if type(k) == 'string' and (sep ~= ':' or type(v) == "function") then
|
||||||
|
add(k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif sep == '[' then
|
||||||
|
if t == 'table' then
|
||||||
|
for k in pairs(v) do
|
||||||
|
if type(k) == 'number' then
|
||||||
|
add(k .. "]")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if word ~= "" then add_globals() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #matches == 0 then
|
||||||
|
add_globals()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function find_unmatch(str, openpar, pair)
|
local function find_unmatch(str, openpar, pair)
|
||||||
local done = false
|
local done = false
|
||||||
@ -56,46 +125,81 @@ return ln.linenoise('\x1b[1;36m[MAME]\x1b[0m> ')
|
|||||||
return str
|
return str
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_completions(str)
|
-- This complex function tries to simplify the input line, by removing
|
||||||
local comps = ","
|
-- literal strings, full table constructors and balanced groups of
|
||||||
local rest, dot, last = str:match("(.-)([.:]?)([^.:]*)$")
|
-- parentheses. Returns the sub-expression preceding the word, the
|
||||||
str = find_unmatch(str, "%(", "%b()")
|
-- separator item ( '.', ':', '[', '(' ) and the current string in case
|
||||||
str = find_unmatch(str, "%[", "%b[]")
|
-- of an unfinished string literal.
|
||||||
local table = str:match("([%w_%.:%(%)%[%]]-)[:.][%w_]*$")
|
local function simplify_expression(expr, word)
|
||||||
local err
|
-- Replace annoying sequences \' and \" inside literal strings
|
||||||
if rest == "" or not table then
|
expr = expr:gsub("\\(['\"])", function (c)
|
||||||
if dot == "" then
|
return string.format("\\%03d", string.byte(c))
|
||||||
table = "_G"
|
end)
|
||||||
|
local curstring
|
||||||
|
-- Remove (finished and unfinished) literal strings
|
||||||
|
while true do
|
||||||
|
local idx1, _, equals = expr:find("%[(=*)%[")
|
||||||
|
local idx2, _, sign = expr:find("(['\"])")
|
||||||
|
if idx1 == nil and idx2 == nil then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
local idx, startpat, endpat
|
||||||
|
if (idx1 or math.huge) < (idx2 or math.huge) then
|
||||||
|
idx, startpat, endpat = idx1, "%[" .. equals .. "%[", "%]" .. equals .. "%]"
|
||||||
else
|
else
|
||||||
return comps
|
idx, startpat, endpat = idx2, sign, sign
|
||||||
|
end
|
||||||
|
if expr:sub(idx):find("^" .. startpat .. ".-" .. endpat) then
|
||||||
|
expr = expr:gsub(startpat .. "(.-)" .. endpat, " STRING ")
|
||||||
|
else
|
||||||
|
expr = expr:gsub(startpat .. "(.*)", function (str)
|
||||||
|
curstring = str
|
||||||
|
return "(CURSTRING "
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
err, tablef = pcall(load("return " .. table))
|
-- crop string at unmatched open paran
|
||||||
if (not err) or (not tablef) then
|
expr = find_unmatch(expr, "%(", "%b()")
|
||||||
return comps
|
expr = find_unmatch(expr, "%[", "%b[]")
|
||||||
|
--expr = expr:gsub("%b()"," PAREN ") -- Remove groups of parentheses
|
||||||
|
expr = expr:gsub("%b{}"," TABLE ") -- Remove table constructors
|
||||||
|
-- Avoid two consecutive words without operator
|
||||||
|
expr = expr:gsub("(%w)%s+(%w)","%1|%2")
|
||||||
|
expr = expr:gsub("%s+", "") -- Remove now useless spaces
|
||||||
|
-- This main regular expression looks for table indexes and function calls.
|
||||||
|
return curstring, expr:match("([%.:%w%(%)%[%]_]-)([:%.%[%(])" .. word .. "$")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_completions(line, endpos)
|
||||||
|
matches = {}
|
||||||
|
local endstr = line:sub(endpos + 1, -1)
|
||||||
|
line = line:sub(1, endpos)
|
||||||
|
endstr = endstr or ""
|
||||||
|
local start, word = line:match("^(.*[ \t\n\"\\'><=;:%+%-%*/%%^~#{}%(%)%[%].,])(.-)$")
|
||||||
|
if not start then
|
||||||
|
start = ""
|
||||||
|
word = word or line
|
||||||
|
else
|
||||||
|
word = word or ""
|
||||||
end
|
end
|
||||||
rest = rest .. dot
|
|
||||||
if type(tablef) == 'table' then
|
local str, expr, sep = simplify_expression(line, word)
|
||||||
for k, v in pairs(tablef) do
|
contextual_list(expr, sep, str, word)
|
||||||
if k:match("^" .. last) then
|
if #matches > 1 then
|
||||||
comps = comps .. "," .. rest .. k
|
print("\n")
|
||||||
end
|
for k, v in pairs(matches) do
|
||||||
|
print(v)
|
||||||
end
|
end
|
||||||
|
return "\x01" .. "-1"
|
||||||
|
elseif #matches == 1 then
|
||||||
|
return start .. matches[1] .. endstr .. "\x01" .. (#start + #matches[1])
|
||||||
end
|
end
|
||||||
if type(tablef) == "userdata" then
|
return "\x01" .. "-1"
|
||||||
local tablef = getmetatable(tablef)
|
|
||||||
for k, v in pairs(tablef) do
|
|
||||||
if k:match("^" .. last) then
|
|
||||||
comps = comps .. "," .. rest .. k
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return comps
|
|
||||||
end
|
end
|
||||||
|
|
||||||
emu.register_periodic(function()
|
emu.register_periodic(function()
|
||||||
if conth.yield then
|
if conth.yield then
|
||||||
conth:continue(get_completions(conth.result))
|
conth:continue(get_completions(conth.result:match("([^\x01]*)\x01(.*)")))
|
||||||
return
|
return
|
||||||
elseif conth.busy then
|
elseif conth.busy then
|
||||||
return
|
return
|
||||||
|
@ -574,7 +574,7 @@ project "lualibs"
|
|||||||
}
|
}
|
||||||
if (_OPTIONS["osd"] ~= "uwp") then
|
if (_OPTIONS["osd"] ~= "uwp") then
|
||||||
includedirs {
|
includedirs {
|
||||||
MAME_DIR .. "3rdparty/linenoise-ng/include",
|
MAME_DIR .. "3rdparty/linenoise",
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
includedirs {
|
includedirs {
|
||||||
@ -1631,10 +1631,10 @@ end
|
|||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
-- linenoise-ng library
|
-- linenoise library
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
if (_OPTIONS["osd"] ~= "uwp") then
|
if (_OPTIONS["osd"] ~= "uwp") then
|
||||||
project "linenoise-ng"
|
project "linenoise"
|
||||||
uuid "7320ffc8-2748-4add-8864-ae29b72a8511"
|
uuid "7320ffc8-2748-4add-8864-ae29b72a8511"
|
||||||
kind (LIBTYPE)
|
kind (LIBTYPE)
|
||||||
|
|
||||||
@ -1648,13 +1648,12 @@ project "linenoise-ng"
|
|||||||
configuration { }
|
configuration { }
|
||||||
|
|
||||||
includedirs {
|
includedirs {
|
||||||
MAME_DIR .. "3rdparty/linenoise-ng/include",
|
MAME_DIR .. "3rdparty/linenoise",
|
||||||
}
|
}
|
||||||
|
|
||||||
files {
|
files {
|
||||||
MAME_DIR .. "3rdparty/linenoise-ng/src/ConvertUTF.cpp",
|
MAME_DIR .. "3rdparty/linenoise/utf8.c",
|
||||||
MAME_DIR .. "3rdparty/linenoise-ng/src/linenoise.cpp",
|
MAME_DIR .. "3rdparty/linenoise/linenoise.c",
|
||||||
MAME_DIR .. "3rdparty/linenoise-ng/src/wcwidth.cpp",
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ if (STANDALONE~=true) then
|
|||||||
}
|
}
|
||||||
if (_OPTIONS["osd"] ~= "uwp") then
|
if (_OPTIONS["osd"] ~= "uwp") then
|
||||||
links {
|
links {
|
||||||
"linenoise-ng",
|
"linenoise",
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user