Skip to content

Commit

Permalink
fix: restore stdin execution
Browse files Browse the repository at this point in the history
also accepts dash arguments as input from stdin when multiple files
  • Loading branch information
jaromil committed Nov 25, 2024
1 parent afa906b commit 3ea2a27
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 62 deletions.
47 changes: 41 additions & 6 deletions src/cjit.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
// from file.c
extern long file_size(const char *filename);
extern char* file_load(const char *filename);
extern char *load_stdin();
extern char* dir_load(const char *path);
extern bool rm_recursive(char *path);
#ifdef LIBC_MINGW32
Expand Down Expand Up @@ -181,7 +182,10 @@ int main(int argc, char **argv) {
else if (c == '?') _err("unknown opt: -%c\n", opt.opt? opt.opt : ':');
else if (c == ':') _err("missing arg: -%c\n", opt.opt? opt.opt : ':');
}
//////////////////////////////////////
// initialize the tmpdir for execution
// from here onwards use goto endgame
// as the main and only exit
#ifndef LIBC_MINGW32
tmpdir = mkdtemp(tmptemplate);
#else
Expand All @@ -204,10 +208,14 @@ int main(int argc, char **argv) {
#endif

if (argc == 0 ) {
_err("No input file: live mode");
_err("No input file: live mode!");
live_mode = true;
}
if(live_mode) {
if (!isatty(fileno(stdin))) {
_err("Live mode only available in terminal (tty not found)");
goto endgame;
}
#ifdef REPL_SUPPORTED
res = cjit_cli_kilo(TCC);
#else
Expand All @@ -216,11 +224,38 @@ int main(int argc, char **argv) {
goto endgame;
}

_err("Source code:");
for (i = opt.ind; i < argc; ++i) {
const char *code_path = argv[i];
_err("+ %s",code_path);
tcc_add_file(TCC, code_path);
char *stdin_code = NULL;
if(opt.ind >= argc) {
_err("No files specified on commandline, reading code from stdin\n");
stdin_code = load_stdin(); // allocated returned buffer, needs free
if(!stdin_code) {
_err("Error reading from standard input");
goto endgame;
}
if( tcc_compile_string(TCC,stdin_code) < 0) {
_err("Code runtime error in stdin");
free(stdin_code);
goto endgame;
}
} else {
_err("Source code:");
for (i = opt.ind; i < argc; ++i) {
const char *code_path = argv[i];
_err("%c %s",(*code_path=='-'?'|':'+'),
(*code_path=='-'?"standard input":code_path));
if(*code_path=='-') { // stdin explicit
stdin_code = load_stdin(); // allocated returned buffer, needs free
if(!stdin_code) {
_err("Error reading from standard input");
} else if( tcc_compile_string(TCC,stdin_code) < 0) {
_err("Code runtime error in stdin");
free(stdin_code);
goto endgame;
} else free(stdin_code);
} else { // load any file path
tcc_add_file(TCC, code_path);
}
}
}
// error handler callback for TCC
tcc_set_error_func(TCC, stderr, handle_error);
Expand Down
26 changes: 26 additions & 0 deletions src/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,32 @@ char* file_load(const char *filename) {
return contents;
}

char *load_stdin() {
char *code = NULL;
char *line = NULL;
size_t len = 0;
ssize_t rd;
fflush(stdout);
fflush(stderr);
while(1) {
rd = getline(&line, &len, stdin);
if(rd == -1) { // ctrl+d
free(line);
break;
}
code = realloc(code, (code?strlen(code):0) + len + 1);
if (!code) {
_err("Memory allocation error");
free(line);
return NULL;
}
strcat(code, line);
free(line);
line = NULL;
}
return(code);
}

bool write_to_file(char *path, char *filename, char *buf, unsigned int len) {
FILE *fd;
size_t written;
Expand Down
103 changes: 47 additions & 56 deletions src/repl.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,73 +338,64 @@ int cjit_cli_tty(TCCState *TCC) {
_err("Memory allocation error");
return 2;
}
// don't add automatic main preamble if in a pipe
if (isatty(fileno(stdin)))
strcpy(code, intro);
else
_err("Not running from a terminal though.\n");

strcpy(code, intro);
#ifdef LIBC_MINGW32
_err("Missing source code argument");
#else // LIBC_MINGW32
while (1) {
// don't print prompt if we are in a pipe
if (isatty(fileno(stdin)))
printf("cjit> ");
fflush(stdout);
rd = getline(&line, &len, stdin);
if (rd == -1) {
/* This is CTRL + D */
code = realloc(code, strlen(code) + 4);
if (!code) {
_err("Memory allocation error");
res = 2;
break;
}
free(line);
line = NULL;
if (isatty(fileno(stdin)))
strcat(code, "\n}\n");

// run the code from main
printf("cjit> ");
fflush(stdout);
rd = getline(&line, &len, stdin);
if (rd == -1) {
/* This is CTRL + D */
code = realloc(code, strlen(code) + 4);
if (!code) {
_err("Memory allocation error");
res = 2;
break;
}
free(line);
line = NULL;
strcat(code, "\n}\n");
// run the code from main
#ifdef VERBOSE_CLI
_err("Compiling code\n");
_err("-----------------------------------\n");
_err("%s\n", code);
_err("-----------------------------------\n");
_err("Compiling code\n");
_err("-----------------------------------\n");
_err("%s\n", code);
_err("-----------------------------------\n");
#endif // VERBOSE_CLI
if (tcc_compile_string(TCC, code) < 0) {
_err("Code runtime error in source\n");
res = 1;
break;
}
if (tcc_relocate(TCC) < 0) {
_err("Code relocation error in source\n");
res = 1;
break;
}
if (tcc_compile_string(TCC, code) < 0) {
_err("Code runtime error in source\n");
res = 1;
break;
}
if (tcc_relocate(TCC) < 0) {
_err("Code relocation error in source\n");
res = 1;
break;
}
#ifdef VERBOSE_CLI
_err("Running code\n");
_err("-----------------------------------\n");
_err("Running code\n");
_err("-----------------------------------\n");
#endif // VERBOSE_CLI
#ifndef LIBC_MINGW32
res = cjit_exec_fork(TCC, "main", 0, NULL);
res = cjit_exec_fork(TCC, "main", 0, NULL);
#else // LIBC_MINGW32
res = cjit_exec_win(TCC, "main", 0, NULL);
res = cjit_exec_win(TCC, "main", 0, NULL);
#endif // LIBC_MINGW32
free(code);
code = NULL;
break;
}
code = realloc(code, strlen(code) + len + 1);
if (!code) {
_err("Memory allocation error");
res = 2;
break;
}
strcat(code, line);
free(line);
line = NULL;
free(code);
code = NULL;
break;
}
code = realloc(code, strlen(code) + len + 1);
if (!code) {
_err("Memory allocation error");
res = 2;
break;
}
strcat(code, line);
free(line);
line = NULL;
}
#endif // LIBC_MINGW32
return res;
Expand Down

0 comments on commit 3ea2a27

Please sign in to comment.