Skip to content

Commit

Permalink
Replace term_readline to term_readln
Browse files Browse the repository at this point in the history
  • Loading branch information
dd86k committed Mar 4, 2024
1 parent 68c1bdc commit 8011e57
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 17 deletions.
14 changes: 7 additions & 7 deletions app/shell.d
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ void registerHelp(void function(ref command2_help_t help)) {
}*/

int shell_loop() {
// Load process if CLI specified it
// Load or attach process if CLI specified it
if (globals.file) {
if (adbg_debugger_spawn(&process, globals.file,
AdbgSpawnOpt.argv, globals.args, 0))
Expand Down Expand Up @@ -123,16 +123,17 @@ int shell_loop() {
term_init;

LINPUT:
printf("(adbg) "); // print prompt
char* line = term_readline(null); // read line
printf("(adbg) ");

// .ptr is temporary because a slice with a length of 0
// also make its pointer null.
char* line = term_readln().ptr;

//TODO: remove once term gets key events
if (line == null) {
printf("^D");
return 0;
}

int error = shell_exec(line); // execute line
int error = shell_exec(line);
if (error)
printf("error: %s\n", errorstring(cast(ShellError)error));
goto LINPUT;
Expand All @@ -156,7 +157,6 @@ int shell_execv(int argc, const(char) **argv) {
serror("unknown command: '%s'", ucommand);
return ShellError.invalidCommand;
}

return command.entry(argc, argv);
}

Expand Down
44 changes: 35 additions & 9 deletions app/term.d
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import core.stdc.stdio;

extern (C):

private
int putchar(int);
private int putchar(int);
private int getchar();

version (Windows) {
private import core.sys.windows.windows;
Expand Down Expand Up @@ -358,17 +358,43 @@ L_END:
}
}

//TODO: Consider redoing with getchar+fwrite(stdin)
// onSpecial: tab, ^D, etc.
// make onError?
/// Read a line from stdin.
/// Params:
/// onSpecial = (Not implemented) Callback on special characters
/// Returns: Character slice; Or null on error.
char[] term_readln(void function(int) onSpecial = null) {
import core.stdc.ctype : isprint;

// GNU readline has this set to 512
enum BUFFERSIZE = 1024;

__gshared char* buffer;

if (buffer == null) {
buffer = cast(char*)malloc(BUFFERSIZE);
if (buffer == null)
return null;
}

// NOTE: stdin is line-buffered by the host console/terminal
// Once it sees a newline, it returns, and we copy up until the newline
size_t i;
LFETCHC:
int c = getchar();
if (c == '\n' || c == EOF) {
buffer[i] = 0;
return buffer[0..i];
}
buffer[i++] = cast(char)c;
goto LFETCHC;
}

//TODO: term_readline_event(Key, void function(Key))
// or just term_event_ctrld (etc.)
//TODO: damage-based display (putchar)
// instead of reprinting the whole string at every stroke
// yes, it's very noticeable on windows (because of cursor positioning?)
//TODO: Use realloc with enum INITBSZ = 2048
/// Read a line from input keystrokes
/// Params: length = Pointer that will contain the number of characters in the buffer
/// Returns: Internal buffer pointer
deprecated("Use term_readln")
char* term_readline(int *length) {
enum BUFFER_SIZE = 1024;
__gshared char[BUFFER_SIZE] buffer;
Expand Down
7 changes: 6 additions & 1 deletion dub.sdl
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ buildType "release-nobounds-static" {
}

#
# ANCHOR Unit tests
# ANCHOR Integration tests
#
# NOTE: These MUST be ran as "dub test -b TEST"
# NOTE: Dedicated tests must only exist if one of these conditions are met
Expand All @@ -145,6 +145,11 @@ buildType "readline" {
sourceFiles "tests/readline.d"
sourcePaths "app" "src"
}
buildType "readln" {
buildOptions "unittests"
sourceFiles "tests/readln.d"
sourceFiles "app/term.d"
}

#
# ANCHOR Examples
Expand Down
21 changes: 21 additions & 0 deletions tests/readln.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module tests.readln;

import core.stdc.stdio;
import core.stdc.ctype : isprint;
import term;

extern (C) int putchar(int);

unittest {
while (true) {
printf("prompt: ");
char[] input = term_readln();
foreach (char c; input)
if (isprint(c))
putchar(c);
else
printf("\\x%02x", c);
putchar('\n');
printf("buffer had %d characters\n", cast(int)input.length);
}
}

0 comments on commit 8011e57

Please sign in to comment.