mirror of
https://github.com/CPunch/Cosmo.git
synced 2025-10-15 13:40:10 +00:00
Compare commits
13 Commits
error-hand
...
5a00d61646
Author | SHA1 | Date | |
---|---|---|---|
5a00d61646 | |||
83dfd36c5c | |||
2d889a37d1 | |||
0f0a8fb085 | |||
c03df8f506 | |||
38d9c499ea | |||
79d40d4bb0 | |||
dc44adba6e | |||
7c0bec5e6c | |||
a44450ff22 | |||
58c857d2ea | |||
38136d028f | |||
420cd3e856 |
45
.github/workflows/check_build.yaml
vendored
Normal file
45
.github/workflows/check_build.yaml
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
name: Check Builds
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- src/**
|
||||||
|
- util/**
|
||||||
|
- main.c
|
||||||
|
- Makefile
|
||||||
|
- CMakeLists.txt
|
||||||
|
- .github/workflows/check_build.yaml
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ubuntu-build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: CMake
|
||||||
|
run: cmake -B build
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build build
|
||||||
|
- name: Upload build artifact
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Cosmo-Ubuntu
|
||||||
|
path: build/bin
|
||||||
|
|
||||||
|
windows-build:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: Create CMake build files
|
||||||
|
run: cmake -B build -DCMAKE_BUILD_TYPE=MinSizeRel
|
||||||
|
- name: Check compilation
|
||||||
|
run: cmake --build build --config MinSizeRel
|
||||||
|
- name: Upload build artifact
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Cosmo-Windows
|
||||||
|
path: build/bin
|
@@ -16,7 +16,7 @@ set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT c
|
|||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
|
||||||
file(GLOB sources CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/src/*.c)
|
file(GLOB sources CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/src/*.c)
|
||||||
add_executable(${PROJECT_NAME} main.c)
|
add_executable(${PROJECT_NAME} main.c ${PROJECT_SOURCE_DIR}/util/linenoise.c)
|
||||||
target_sources(${PROJECT_NAME} PRIVATE ${sources})
|
target_sources(${PROJECT_NAME} PRIVATE ${sources})
|
||||||
|
|
||||||
IF (NOT WIN32)
|
IF (NOT WIN32)
|
||||||
|
2
Makefile
2
Makefile
@@ -21,6 +21,7 @@ CHDR=\
|
|||||||
src/cbaselib.h\
|
src/cbaselib.h\
|
||||||
src/cdump.h\
|
src/cdump.h\
|
||||||
src/cundump.h\
|
src/cundump.h\
|
||||||
|
util/linenoise.h\
|
||||||
|
|
||||||
CSRC=\
|
CSRC=\
|
||||||
src/cchunk.c\
|
src/cchunk.c\
|
||||||
@@ -37,6 +38,7 @@ CSRC=\
|
|||||||
src/cbaselib.c\
|
src/cbaselib.c\
|
||||||
src/cdump.c\
|
src/cdump.c\
|
||||||
src/cundump.c\
|
src/cundump.c\
|
||||||
|
util/linenoise.c\
|
||||||
main.c\
|
main.c\
|
||||||
|
|
||||||
COBJ=$(CSRC:.c=.o)
|
COBJ=$(CSRC:.c=.o)
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
# Cosmo
|
# Cosmo
|
||||||
[](https://ci.appveyor.com/project/CPunch/Cosmo)
|
[](https://github.com/CPunch/Cosmo/actions/workflows/check_build.yaml)
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
33
appveyor.yml
33
appveyor.yml
@@ -1,33 +0,0 @@
|
|||||||
version: 'cosmo-0.1.{build}'
|
|
||||||
|
|
||||||
# we compile every commit under all branches
|
|
||||||
#branch:
|
|
||||||
# only:
|
|
||||||
# - main
|
|
||||||
|
|
||||||
# only run CI if we changed actual code
|
|
||||||
only_commits:
|
|
||||||
files:
|
|
||||||
- src/
|
|
||||||
- main.c
|
|
||||||
- Makefile
|
|
||||||
- CMakeLists.txt
|
|
||||||
- appveyor.yml
|
|
||||||
|
|
||||||
# images we're using
|
|
||||||
image:
|
|
||||||
- Ubuntu2004
|
|
||||||
|
|
||||||
platform:
|
|
||||||
- x64
|
|
||||||
|
|
||||||
install:
|
|
||||||
- sudo apt install clang cmake -y
|
|
||||||
|
|
||||||
build_script:
|
|
||||||
- make && ./bin/cosmo examples/testsuite.cosmo -s examples/getters_setters.cosmo
|
|
||||||
|
|
||||||
artifacts:
|
|
||||||
- path: bin
|
|
||||||
name: ubuntu20_04-bin-x64
|
|
||||||
type: zip
|
|
11
main.c
11
main.c
@@ -8,6 +8,8 @@
|
|||||||
#include "cundump.h"
|
#include "cundump.h"
|
||||||
#include "cvm.h"
|
#include "cvm.h"
|
||||||
|
|
||||||
|
#include "util/linenoise.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -63,7 +65,7 @@ static bool interpret(CState *state, const char *script, const char *mod)
|
|||||||
|
|
||||||
static void repl(CState *state)
|
static void repl(CState *state)
|
||||||
{
|
{
|
||||||
char line[1024];
|
char *line;
|
||||||
_ACTIVE = true;
|
_ACTIVE = true;
|
||||||
|
|
||||||
// add our custom REPL functions
|
// add our custom REPL functions
|
||||||
@@ -76,14 +78,13 @@ static void repl(CState *state)
|
|||||||
cosmoV_register(state, 2);
|
cosmoV_register(state, 2);
|
||||||
|
|
||||||
while (_ACTIVE) {
|
while (_ACTIVE) {
|
||||||
printf("> ");
|
if (!(line = linenoise("> "))) { // better than gets()
|
||||||
|
|
||||||
if (!fgets(line, sizeof(line), stdin)) { // better than gets()
|
|
||||||
printf("\n> ");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
linenoiseHistoryAdd(line);
|
||||||
interpret(state, line, "REPL");
|
interpret(state, line, "REPL");
|
||||||
|
free(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -56,7 +56,7 @@ void *cosmoM_reallocate(CState *state, void *buf, size_t oldSize, size_t newSize
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (newBuf == NULL) {
|
if (newBuf == NULL) {
|
||||||
CERROR("failed to allocate memory!");
|
printf("[ERROR] failed to allocate memory!");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -64,6 +64,4 @@ typedef int (*cosmo_Writer)(CState *state, const void *data, size_t size, const
|
|||||||
#define UNNAMEDCHUNK "_main"
|
#define UNNAMEDCHUNK "_main"
|
||||||
#define COSMOASSERT(x) assert(x)
|
#define COSMOASSERT(x) assert(x)
|
||||||
|
|
||||||
#define CERROR(err) printf("%s : %s\n", "[ERROR]", err)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -32,7 +32,7 @@ CState *cosmoV_newState()
|
|||||||
CState *state = malloc(sizeof(CState));
|
CState *state = malloc(sizeof(CState));
|
||||||
|
|
||||||
if (state == NULL) {
|
if (state == NULL) {
|
||||||
CERROR("failed to allocate memory!");
|
printf("[ERROR] failed to allocate memory!");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -696,7 +696,7 @@ static inline uint16_t READUINT(CCallFrame *frame)
|
|||||||
# define SWITCH switch (READBYTE(frame))
|
# define SWITCH switch (READBYTE(frame))
|
||||||
# define DEFAULT \
|
# define DEFAULT \
|
||||||
default: \
|
default: \
|
||||||
CERROR("unknown opcode!"); \
|
printf("[ERROR] unknown opcode!"); \
|
||||||
exit(0)
|
exit(0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
379
util/linenoise-win32.c
Normal file
379
util/linenoise-win32.c
Normal file
@@ -0,0 +1,379 @@
|
|||||||
|
|
||||||
|
/* this code is not standalone
|
||||||
|
* it is included into linenoise.c
|
||||||
|
* for windows.
|
||||||
|
* It is deliberately kept separate so that
|
||||||
|
* applications that have no need for windows
|
||||||
|
* support can omit this
|
||||||
|
*/
|
||||||
|
static DWORD orig_consolemode = 0;
|
||||||
|
|
||||||
|
static int flushOutput(struct current *current);
|
||||||
|
static void outputNewline(struct current *current);
|
||||||
|
|
||||||
|
static void refreshStart(struct current *current)
|
||||||
|
{
|
||||||
|
(void)current;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void refreshEnd(struct current *current)
|
||||||
|
{
|
||||||
|
(void)current;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void refreshStartChars(struct current *current)
|
||||||
|
{
|
||||||
|
assert(current->output == NULL);
|
||||||
|
/* We accumulate all output here */
|
||||||
|
current->output = sb_alloc();
|
||||||
|
#ifdef USE_UTF8
|
||||||
|
current->ubuflen = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void refreshNewline(struct current *current)
|
||||||
|
{
|
||||||
|
DRL("<nl>");
|
||||||
|
outputNewline(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void refreshEndChars(struct current *current)
|
||||||
|
{
|
||||||
|
assert(current->output);
|
||||||
|
flushOutput(current);
|
||||||
|
sb_free(current->output);
|
||||||
|
current->output = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int enableRawMode(struct current *current) {
|
||||||
|
DWORD n;
|
||||||
|
INPUT_RECORD irec;
|
||||||
|
|
||||||
|
current->outh = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
current->inh = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
|
||||||
|
if (!PeekConsoleInput(current->inh, &irec, 1, &n)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (getWindowSize(current) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (GetConsoleMode(current->inh, &orig_consolemode)) {
|
||||||
|
SetConsoleMode(current->inh, ENABLE_PROCESSED_INPUT);
|
||||||
|
}
|
||||||
|
#ifdef USE_UTF8
|
||||||
|
/* XXX is this the right thing to do? */
|
||||||
|
SetConsoleCP(65001);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void disableRawMode(struct current *current)
|
||||||
|
{
|
||||||
|
SetConsoleMode(current->inh, orig_consolemode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void linenoiseClearScreen(void)
|
||||||
|
{
|
||||||
|
/* XXX: This is ugly. Should just have the caller pass a handle */
|
||||||
|
struct current current;
|
||||||
|
|
||||||
|
current.outh = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
|
if (getWindowSize(¤t) == 0) {
|
||||||
|
COORD topleft = { 0, 0 };
|
||||||
|
DWORD n;
|
||||||
|
|
||||||
|
FillConsoleOutputCharacter(current.outh, ' ',
|
||||||
|
current.cols * current.rows, topleft, &n);
|
||||||
|
FillConsoleOutputAttribute(current.outh,
|
||||||
|
FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN,
|
||||||
|
current.cols * current.rows, topleft, &n);
|
||||||
|
SetConsoleCursorPosition(current.outh, topleft);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cursorToLeft(struct current *current)
|
||||||
|
{
|
||||||
|
COORD pos;
|
||||||
|
DWORD n;
|
||||||
|
|
||||||
|
pos.X = 0;
|
||||||
|
pos.Y = (SHORT)current->y;
|
||||||
|
|
||||||
|
FillConsoleOutputAttribute(current->outh,
|
||||||
|
FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN, current->cols, pos, &n);
|
||||||
|
current->x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_UTF8
|
||||||
|
static void flush_ubuf(struct current *current)
|
||||||
|
{
|
||||||
|
COORD pos;
|
||||||
|
DWORD nwritten;
|
||||||
|
pos.Y = (SHORT)current->y;
|
||||||
|
pos.X = (SHORT)current->x;
|
||||||
|
SetConsoleCursorPosition(current->outh, pos);
|
||||||
|
WriteConsoleW(current->outh, current->ubuf, current->ubuflen, &nwritten, 0);
|
||||||
|
current->x += current->ubufcols;
|
||||||
|
current->ubuflen = 0;
|
||||||
|
current->ubufcols = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_ubuf(struct current *current, int ch)
|
||||||
|
{
|
||||||
|
/* This code originally by: Author: Mark E. Davis, 1994. */
|
||||||
|
static const int halfShift = 10; /* used for shifting by 10 bits */
|
||||||
|
|
||||||
|
static const DWORD halfBase = 0x0010000UL;
|
||||||
|
static const DWORD halfMask = 0x3FFUL;
|
||||||
|
|
||||||
|
#define UNI_SUR_HIGH_START 0xD800
|
||||||
|
#define UNI_SUR_HIGH_END 0xDBFF
|
||||||
|
#define UNI_SUR_LOW_START 0xDC00
|
||||||
|
#define UNI_SUR_LOW_END 0xDFFF
|
||||||
|
|
||||||
|
#define UNI_MAX_BMP 0x0000FFFF
|
||||||
|
|
||||||
|
if (ch > UNI_MAX_BMP) {
|
||||||
|
/* convert from unicode to utf16 surrogate pairs
|
||||||
|
* There is always space for one extra word in ubuf
|
||||||
|
*/
|
||||||
|
ch -= halfBase;
|
||||||
|
current->ubuf[current->ubuflen++] = (WORD)((ch >> halfShift) + UNI_SUR_HIGH_START);
|
||||||
|
current->ubuf[current->ubuflen++] = (WORD)((ch & halfMask) + UNI_SUR_LOW_START);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
current->ubuf[current->ubuflen++] = ch;
|
||||||
|
}
|
||||||
|
current->ubufcols += utf8_width(ch);
|
||||||
|
if (current->ubuflen >= UBUF_MAX_CHARS) {
|
||||||
|
flush_ubuf(current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int flushOutput(struct current *current)
|
||||||
|
{
|
||||||
|
const char *pt = sb_str(current->output);
|
||||||
|
int len = sb_len(current->output);
|
||||||
|
|
||||||
|
#ifdef USE_UTF8
|
||||||
|
/* convert utf8 in current->output into utf16 in current->ubuf
|
||||||
|
*/
|
||||||
|
while (len) {
|
||||||
|
int ch;
|
||||||
|
int n = utf8_tounicode(pt, &ch);
|
||||||
|
|
||||||
|
pt += n;
|
||||||
|
len -= n;
|
||||||
|
|
||||||
|
add_ubuf(current, ch);
|
||||||
|
}
|
||||||
|
flush_ubuf(current);
|
||||||
|
#else
|
||||||
|
DWORD nwritten;
|
||||||
|
COORD pos;
|
||||||
|
|
||||||
|
pos.Y = (SHORT)current->y;
|
||||||
|
pos.X = (SHORT)current->x;
|
||||||
|
|
||||||
|
SetConsoleCursorPosition(current->outh, pos);
|
||||||
|
WriteConsoleA(current->outh, pt, len, &nwritten, 0);
|
||||||
|
|
||||||
|
current->x += len;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sb_clear(current->output);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int outputChars(struct current *current, const char *buf, int len)
|
||||||
|
{
|
||||||
|
if (len < 0) {
|
||||||
|
len = strlen(buf);
|
||||||
|
}
|
||||||
|
assert(current->output);
|
||||||
|
|
||||||
|
sb_append_len(current->output, buf, len);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void outputNewline(struct current *current)
|
||||||
|
{
|
||||||
|
/* On the last row output a newline to force a scroll */
|
||||||
|
if (current->y + 1 == current->rows) {
|
||||||
|
outputChars(current, "\n", 1);
|
||||||
|
}
|
||||||
|
flushOutput(current);
|
||||||
|
current->x = 0;
|
||||||
|
current->y++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setOutputHighlight(struct current *current, const int *props, int nprops)
|
||||||
|
{
|
||||||
|
int colour = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN;
|
||||||
|
int bold = 0;
|
||||||
|
int reverse = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < nprops; i++) {
|
||||||
|
switch (props[i]) {
|
||||||
|
case 0:
|
||||||
|
colour = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN;
|
||||||
|
bold = 0;
|
||||||
|
reverse = 0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
bold = FOREGROUND_INTENSITY;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
reverse = 1;
|
||||||
|
break;
|
||||||
|
case 30:
|
||||||
|
colour = 0;
|
||||||
|
break;
|
||||||
|
case 31:
|
||||||
|
colour = FOREGROUND_RED;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
colour = FOREGROUND_GREEN;
|
||||||
|
break;
|
||||||
|
case 33:
|
||||||
|
colour = FOREGROUND_RED | FOREGROUND_GREEN;
|
||||||
|
break;
|
||||||
|
case 34:
|
||||||
|
colour = FOREGROUND_BLUE;
|
||||||
|
break;
|
||||||
|
case 35:
|
||||||
|
colour = FOREGROUND_RED | FOREGROUND_BLUE;
|
||||||
|
break;
|
||||||
|
case 36:
|
||||||
|
colour = FOREGROUND_BLUE | FOREGROUND_GREEN;
|
||||||
|
break;
|
||||||
|
case 37:
|
||||||
|
colour = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flushOutput(current);
|
||||||
|
|
||||||
|
if (reverse) {
|
||||||
|
SetConsoleTextAttribute(current->outh, BACKGROUND_INTENSITY);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SetConsoleTextAttribute(current->outh, colour | bold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void eraseEol(struct current *current)
|
||||||
|
{
|
||||||
|
COORD pos;
|
||||||
|
DWORD n;
|
||||||
|
|
||||||
|
pos.X = (SHORT) current->x;
|
||||||
|
pos.Y = (SHORT) current->y;
|
||||||
|
|
||||||
|
FillConsoleOutputCharacter(current->outh, ' ', current->cols - current->x, pos, &n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setCursorXY(struct current *current)
|
||||||
|
{
|
||||||
|
COORD pos;
|
||||||
|
|
||||||
|
pos.X = (SHORT) current->x;
|
||||||
|
pos.Y = (SHORT) current->y;
|
||||||
|
|
||||||
|
SetConsoleCursorPosition(current->outh, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void setCursorPos(struct current *current, int x)
|
||||||
|
{
|
||||||
|
current->x = x;
|
||||||
|
setCursorXY(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cursorUp(struct current *current, int n)
|
||||||
|
{
|
||||||
|
current->y -= n;
|
||||||
|
setCursorXY(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cursorDown(struct current *current, int n)
|
||||||
|
{
|
||||||
|
current->y += n;
|
||||||
|
setCursorXY(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fd_read(struct current *current)
|
||||||
|
{
|
||||||
|
while (1) {
|
||||||
|
INPUT_RECORD irec;
|
||||||
|
DWORD n;
|
||||||
|
if (WaitForSingleObject(current->inh, INFINITE) != WAIT_OBJECT_0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!ReadConsoleInputW(current->inh, &irec, 1, &n)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (irec.EventType == KEY_EVENT) {
|
||||||
|
KEY_EVENT_RECORD *k = &irec.Event.KeyEvent;
|
||||||
|
if (k->bKeyDown || k->wVirtualKeyCode == VK_MENU) {
|
||||||
|
if (k->dwControlKeyState & ENHANCED_KEY) {
|
||||||
|
switch (k->wVirtualKeyCode) {
|
||||||
|
case VK_LEFT:
|
||||||
|
return SPECIAL_LEFT;
|
||||||
|
case VK_RIGHT:
|
||||||
|
return SPECIAL_RIGHT;
|
||||||
|
case VK_UP:
|
||||||
|
return SPECIAL_UP;
|
||||||
|
case VK_DOWN:
|
||||||
|
return SPECIAL_DOWN;
|
||||||
|
case VK_INSERT:
|
||||||
|
return SPECIAL_INSERT;
|
||||||
|
case VK_DELETE:
|
||||||
|
return SPECIAL_DELETE;
|
||||||
|
case VK_HOME:
|
||||||
|
return SPECIAL_HOME;
|
||||||
|
case VK_END:
|
||||||
|
return SPECIAL_END;
|
||||||
|
case VK_PRIOR:
|
||||||
|
return SPECIAL_PAGE_UP;
|
||||||
|
case VK_NEXT:
|
||||||
|
return SPECIAL_PAGE_DOWN;
|
||||||
|
case VK_RETURN:
|
||||||
|
return k->uChar.UnicodeChar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Note that control characters are already translated in AsciiChar */
|
||||||
|
else if (k->wVirtualKeyCode == VK_CONTROL)
|
||||||
|
continue;
|
||||||
|
else {
|
||||||
|
return k->uChar.UnicodeChar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getWindowSize(struct current *current)
|
||||||
|
{
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||||
|
if (!GetConsoleScreenBufferInfo(current->outh, &info)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
current->cols = info.dwSize.X;
|
||||||
|
current->rows = info.dwSize.Y;
|
||||||
|
if (current->cols <= 0 || current->rows <= 0) {
|
||||||
|
current->cols = 80;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
current->y = info.dwCursorPosition.Y;
|
||||||
|
current->x = info.dwCursorPosition.X;
|
||||||
|
return 0;
|
||||||
|
}
|
2786
util/linenoise.c
Normal file
2786
util/linenoise.c
Normal file
File diff suppressed because it is too large
Load Diff
152
util/linenoise.h
Normal file
152
util/linenoise.h
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
/* 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
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef NO_COMPLETION
|
||||||
|
typedef struct linenoiseCompletions {
|
||||||
|
size_t len;
|
||||||
|
char **cvec;
|
||||||
|
} linenoiseCompletions;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The callback type for tab completion handlers.
|
||||||
|
*/
|
||||||
|
typedef void(linenoiseCompletionCallback)(const char *prefix, linenoiseCompletions *comp, void *userdata);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets the current tab completion handler and returns the previous one, or NULL
|
||||||
|
* if no prior one has been set.
|
||||||
|
*/
|
||||||
|
linenoiseCompletionCallback * linenoiseSetCompletionCallback(linenoiseCompletionCallback *comp, void *userdata);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
typedef char*(linenoiseHintsCallback)(const char *, int *color, int *bold, void *userdata);
|
||||||
|
typedef void(linenoiseFreeHintsCallback)(void *hint, void *userdata);
|
||||||
|
void linenoiseSetHintsCallback(linenoiseHintsCallback *callback, void *userdata);
|
||||||
|
void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *callback);
|
||||||
|
|
||||||
|
#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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like linenoise() but starts with an initial buffer.
|
||||||
|
*/
|
||||||
|
char *linenoiseWithInitial(const char *prompt, const char *initial);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable multiline mode (disabled by default)
|
||||||
|
*/
|
||||||
|
void linenoiseSetMultiLine(int enableml);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __LINENOISE_H */
|
Reference in New Issue
Block a user