Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/kilo support #53

Merged
merged 7 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ jobs:
make win-native
- name: Run tests
run: |
make check CJIT=./cjit.exe
make check

osx-native-test:
name: 🍎 OSX native test
Expand All @@ -98,7 +98,7 @@ jobs:
make apple-osx
- name: Run tests
run: |
./cjit.command test/hello.c
make check

semantic-release:
name: 🤖 Semantic release
Expand Down Expand Up @@ -208,8 +208,8 @@ jobs:
path: |
cjit-Darwin-arm64

draft-binary-release:
name: 📦 Pack release
binary-release:
name: 📢 Public release
needs: [semantic-release, osx-native-release, musl-release, linux-release, win-native-release]
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -251,7 +251,7 @@ jobs:

virustotal:
name: 🦠 Virus scan of released binaries
needs: [semantic-release, osx-native-release, win-native-release]
needs: [binary-release, osx-native-release, win-native-release]
runs-on: ubuntu-latest
if: ${{ needs.semantic-release.outputs.new_release_published == 'true' }}
steps:
Expand Down
7 changes: 1 addition & 6 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,7 @@ _: ##

check: CJIT ?= ./cjit
check: ## 🧪 Run all tests using the currently built binary ./cjit
$(if $(wildcard ${CJIT}),,$(error CJIT is not yet built: ${CJIT}))
${CJIT} test/hello.c
${CJIT} test/cflags.c -DALLOWED
${CJIT} test/cflags.c -DALLOWED=1
${CJIT} test/multifile/*
${CJIT} test/cargs.c -- a b c
./test/bats/bin/bats test

_: ##
clean: ## 🧹 Clean the source from all built objects
Expand Down
4 changes: 2 additions & 2 deletions build/linux.mk
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ include build/init.mk

cc := gcc

cflags += -DLIBC_GNU -D_GNU_SOURCE -DREPL_SUPPORTED
cflags += -DLIBC_GNU -D_GNU_SOURCE -DKILO_SUPPORTED

SOURCES += src/kilo.o

ifdef ASAN
cflags := -Og -ggdb -DDEBUG=1 -fno-omit-frame-pointer -fsanitize=address
cflags += ${cflags_includes} ${cflags_gnu} -DREPL_SUPPORTED
cflags += ${cflags_includes} ${cflags_gnu} -DKILO_SUPPORTED
ldflags := -fsanitize=address -static-libasan
# tinycc_config += --extra-ldflags="${ldflags}"
endif
Expand Down
2 changes: 1 addition & 1 deletion build/musl.mk
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ include build/init.mk

cflags := -Wall -static -O2 ${cflags_stack_protect}
cflags += -Isrc -Ilib/tinycc -DLIBC_MUSL -nostdlib
cflags += -DREPL_SUPPORTED
cflags += -DKILO_SUPPORTED

ldadd := lib/tinycc/libtcc.a /usr/lib/x86_64-linux-musl/crt1.o /usr/lib/x86_64-linux-musl/libc.a

Expand Down
47 changes: 30 additions & 17 deletions src/cjit.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
extern char *win32_mkdtemp();
// from win-compat.c
extern void win_compat_usleep(unsigned int microseconds);
extern ssize_t win_compat_getline(char **lineptr, size_t *n, FILE *stream);

Check warning on line 51 in src/cjit.c

View workflow job for this annotation

GitHub Actions / cpplint

[cpplint] src/cjit.c#L51

Add #include <cstdio> for FILE [build/include_what_you_use] [4]
Raw output
src/cjit.c:51:  Add #include <cstdio> for FILE  [build/include_what_you_use] [4]
#else
extern char *posix_mkdtemp();
#endif
Expand All @@ -61,7 +62,7 @@
extern int cjit_exec_fork(TCCState *TCC, const char *ep, int argc, char **argv);
#endif
extern int cjit_cli_tty(TCCState *TCC);
#ifdef REPL_SUPPORTED
#ifdef KILO_SUPPORTED
extern int cjit_cli_kilo(TCCState *TCC);
#endif
/////////////
Expand Down Expand Up @@ -106,6 +107,7 @@
"Options:\n"
" -h \t print this help\n"
" -v \t print version information\n"
" -q \t stay quiet and only print errors and output\n"
" -D sym\t define a macro symbol or key=value\n"
" -C \t set compiler flags (default from env var CFLAGS)\n"
" -I dir\t also search folder 'dir' for header files\n"
Expand All @@ -124,10 +126,10 @@
const char *default_main = "main";
char *entry = (char*)default_main;
bool live_mode = false;
bool quiet = false;
int arg_separator = 0;
int res = 1;
int i, c;
_err("CJIT %s by Dyne.org",VERSION);
TCC = tcc_new();
if (!TCC) {
_err("Could not initialize tcc");
Expand All @@ -148,8 +150,12 @@
{ NULL, 0, 0 }
};
ketopt_t opt = KETOPT_INIT;
while ((c = ketopt(&opt, argc, argv, 1, "hvD:L:l:C:I:e:", longopts)) >= 0) {
while ((c = ketopt(&opt, argc, argv, 1, "qhvD:L:l:C:I:e:", longopts)) >= 0) {
if(c == 'q') {
quiet = true;
}
if (c == 'v') {
_err("CJIT %s by Dyne.org",VERSION);
// _err("Running version: %s\n",VERSION);
// version is always shown
#ifdef LIBC_MINGW32
Expand Down Expand Up @@ -183,28 +189,33 @@
exit(1);
}
} else if (c == 'l') { // library link
_err("lib: %s",opt.arg);
if(!quiet)_err("lib: %s",opt.arg);
tcc_add_library(TCC, opt.arg);
} else if (c == 'C') { // cflags compiler options
_err("cflags: %s",opt.arg);
if(!quiet)_err("cflags: %s",opt.arg);
tcc_set_options(TCC, opt.arg);
} else if (c == 'I') { // include paths in cflags
if(!quiet)_err("inc: %s",opt.arg);
tcc_add_include_path(TCC, opt.arg);
_err("inc: %s",opt.arg);
} else if (c == 'e') { // entry point (default main)
_err("entry: %s",opt.arg);
if(!quiet)_err("entry: %s",opt.arg);
if(entry!=default_main) free(entry);
entry = malloc(strlen(opt.arg)+1);
strcpy(entry,opt.arg);
} else if (c == 301) { //
live_mode = true;
#ifdef LIBC_MINGW32
_err("Live mode not supported in Windows");
#else
if(!quiet)_err("Live mode activated");
live_mode = true;
#endif
} else if (c == 401) { //
#ifndef LIBC_MINGW32
tmpdir = posix_mkdtemp();
#else
tmpdir = win32_mkdtemp();
#endif
_err("Temporary exec dir: %s",tmpdir);
if(!quiet)_err("Temporary exec dir: %s",tmpdir);
tcc_delete(TCC);
exit(0);
}
Expand All @@ -214,6 +225,8 @@
arg_separator = opt.ind+1; break;
}
}
if(!quiet)_err("CJIT %s by Dyne.org",VERSION);

//////////////////////////////////////
// initialize the tmpdir for execution
// from here onwards use goto endgame
Expand All @@ -239,10 +252,9 @@
}

tcc_add_include_path(TCC, tmpdir);
_err("inc: %s",tmpdir);

// finally set paths
_err("lib paths: %s",stored_lib_paths);
// _err("lib paths: %s",stored_lib_paths);
tcc_add_library_path(TCC, stored_lib_paths);

// set output in memory for just in time execution
Expand All @@ -261,7 +273,7 @@
_err("Live mode only available in terminal (tty not found)");
goto endgame;
}
#ifdef REPL_SUPPORTED
#ifdef KILO_SUPPORTED
res = cjit_cli_kilo(TCC);
#else
res = cjit_cli_tty(TCC);
Expand All @@ -278,7 +290,7 @@
_err("No files specified on commandline");
goto endgame;
#endif
_err("No files specified on commandline, reading code from stdin");
if(!quiet)_err("No files specified on commandline, reading code from stdin");
stdin_code = load_stdin(); // allocated returned buffer, needs free
if(!stdin_code) {
_err("Error reading from standard input");
Expand All @@ -291,10 +303,10 @@
}
} else if(opt.ind < left_args) {
// process files on commandline before separator
_err("Source code:");
if(!quiet)_err("Source code:");
for (i = opt.ind; i < left_args; ++i) {
const char *code_path = argv[i];
_err("%c %s",(*code_path=='-'?'|':'+'),
if(!quiet)_err("%c %s",(*code_path=='-'?'|':'+'),
(*code_path=='-'?"standard input":code_path));
if(*code_path=='-') { // stdin explicit
#ifdef LIBC_MINGW32
Expand All @@ -320,6 +332,7 @@
#ifdef LIBC_MINGW32
// add symbols for windows compatibility
tcc_add_symbol(TCC, "usleep", &win_compat_usleep);
tcc_add_symbol(TCC, "getline", &win_compat_getline);
#endif

// relocate the code (link symbols)
Expand All @@ -329,8 +342,8 @@
}

// number of args at the left hand of arg separator, or all of them
int right_args = argc-left_args;//arg_separator? argc-arg_separator : 0;
char **right_argv = &argv[left_args];//arg_separator?&argv[arg_separator]:0
int right_args = argc-left_args+1;//arg_separator? argc-arg_separator : 0;
char **right_argv = &argv[left_args-1];//arg_separator?&argv[arg_separator]:0
#ifndef LIBC_MINGW32
res = cjit_exec_fork(TCC, entry, right_args, right_argv);
#else
Expand Down
16 changes: 8 additions & 8 deletions src/repl.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ int cjit_exec_win(TCCState *TCC, const char *ep, int argc, char **argv) {
_err("Symbol not found in source: %s",ep);
return -1;
}
_err("Execution start\n---");
// _err("Execution start\n---");
res = _ep(argc, argv);
return(res);
}
Expand All @@ -59,7 +59,7 @@ int cjit_exec_fork(TCCState *TCC, const char *ep, int argc, char **argv) {
_err("Symbol not found in source: %s",ep);
return -1;
}
_err("Start execution\n---------------");
// _err("Start execution\n---------------");
pid = fork();
if (pid == 0) {
res = _ep(argc, argv);
Expand All @@ -73,13 +73,13 @@ int cjit_exec_fork(TCCState *TCC, const char *ep, int argc, char **argv) {
}
if (WIFEXITED(status)) {
res = WEXITSTATUS(status);
_err("Process has returned %d", res);
//_err("Process has returned %d", res);
} else if (WIFSIGNALED(status)) {
res = WTERMSIG(status);
_err("Process terminated with signal %d", WTERMSIG(status));
} else if (WIFSTOPPED(status)) {
res = WSTOPSIG(status);
_err("Process has returned %d", WSTOPSIG(status));
//_err("Process has returned %d", WSTOPSIG(status));
} else if (WIFSTOPPED(status)) {
res = WSTOPSIG(status);
_err("Process stopped with signal", WSTOPSIG(status));
Expand All @@ -91,7 +91,7 @@ int cjit_exec_fork(TCCState *TCC, const char *ep, int argc, char **argv) {
}
#endif // LIBC_MINGW32

#ifdef REPL_SUPPORTED
#ifdef KILO_SUPPORTED

// from kilo.c
extern void initEditor(void);
Expand Down Expand Up @@ -193,7 +193,7 @@ int cjit_compile_and_run(TCCState *TCC, const char *code, int argc, char **argv,
_err("Process terminated with signal %d", WTERMSIG(status));
} else if (WIFSTOPPED(status)) {
res = WSTOPSIG(status);
_err("Process has returned %d", WSTOPSIG(status));
//_err("Process has returned %d", WSTOPSIG(status));
} else if (WIFSTOPPED(status)) {
res = WSTOPSIG(status);
_err("Process stopped with signal", WSTOPSIG(status));
Expand Down Expand Up @@ -270,7 +270,7 @@ int cjit_cli_kilo(TCCState *TCC) {
char *code = NULL;
_err("Not running from a terminal, executing source from STDIN\n");
do {
rd = getline(&line, &len, stdin);
rd = getline(&line, &len, stdin);
if (rd > 0) {
if (!code)
code = strdup(line);
Expand Down Expand Up @@ -319,7 +319,7 @@ int cjit_cli_kilo(TCCState *TCC) {
return res;
}

#endif // REPL_SUPPORTED
#endif // KILO_SUPPORTED


int cjit_cli_tty(TCCState *TCC) {
Expand Down
44 changes: 44 additions & 0 deletions src/win-compat.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

// Define the usleep function for Windows
Expand All @@ -6,3 +9,44 @@
unsigned int milliseconds = microseconds >> 10; // /1024;
Sleep(milliseconds);
}

ssize_t win_compat_getline(char **lineptr, size_t *n, FILE *stream) {
size_t pos;
int c;

if (lineptr == NULL || n == NULL || stream == NULL) {
return -1;
}

if (*lineptr == NULL) {
*n = 128; // Initial buffer size
*lineptr = malloc(*n);
if (*lineptr == NULL) {
return -1;
}
}

pos = 0;
while ((c = fgetc(stream)) != EOF) {

Check warning on line 30 in src/win-compat.c

View workflow job for this annotation

GitHub Actions / cpplint

[cpplint] src/win-compat.c#L30

Add #include <cstdio> for fgetc [build/include_what_you_use] [4]
Raw output
src/win-compat.c:30:  Add #include <cstdio> for fgetc  [build/include_what_you_use] [4]
if (pos + 1 >= *n) {
size_t new_size = *n * 2;
char *new_ptr = realloc(*lineptr, new_size);
if (new_ptr == NULL) {
return -1;
}
*lineptr = new_ptr;
*n = new_size;
}
(*lineptr)[pos++] = c;
if (c == '\n') {
break;
}
}

if (pos == 0 && c == EOF) {
return -1;
}

(*lineptr)[pos] = '\0';
return pos;
}
Loading