Fixed bugs with console
This commit is contained in:
@@ -14,5 +14,5 @@ void cmdEcho(const consolecmdexec_t *exec) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
consolePrint("%s", exec->argv[0]);
|
consolePrint("%s\n", exec->argv[0]);
|
||||||
}
|
}
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
// #include "console/cmd/cmdquit.h"
|
|
||||||
#include "console/cmd/cmdecho.h"
|
|
||||||
#include "console/cmd/cmdset.h"
|
|
||||||
#include "console/cmd/cmdget.h"
|
|
||||||
// #include "console/cmd/cmdbind.h"
|
|
||||||
// #include "console/cmd/cmdtoggleconsole.h"
|
|
||||||
// #include "console/cmd/cmdalias.h"
|
|
||||||
|
|
||||||
X(ECHO, "echo", cmdEcho)
|
|
||||||
X(SET, "set", cmdSet)
|
|
||||||
X(GET, "get", cmdGet)
|
|
||||||
+49
-20
@@ -12,8 +12,14 @@
|
|||||||
#include "input/input.h"
|
#include "input/input.h"
|
||||||
#include "log/log.h"
|
#include "log/log.h"
|
||||||
#include "engine/engine.h"
|
#include "engine/engine.h"
|
||||||
|
|
||||||
|
#include "console/cmd/cmdecho.h"
|
||||||
#include "console/cmd/cmdset.h"
|
#include "console/cmd/cmdset.h"
|
||||||
#include "console/cmd/cmdget.h"
|
#include "console/cmd/cmdget.h"
|
||||||
|
#include "console/cmd/cmdquit.h"
|
||||||
|
// #include "console/cmd/cmdbind.h"
|
||||||
|
// #include "console/cmd/cmdtoggleconsole.h"
|
||||||
|
// #include "console/cmd/cmdalias.h"
|
||||||
|
|
||||||
#include "display/shader/shaderunlit.h"
|
#include "display/shader/shaderunlit.h"
|
||||||
#include "display/text/text.h"
|
#include "display/text/text.h"
|
||||||
@@ -30,15 +36,13 @@ void consoleInit() {
|
|||||||
// Register cmds
|
// Register cmds
|
||||||
CONSOLE.cmdGet = consoleRegCmd("get", cmdGet);
|
CONSOLE.cmdGet = consoleRegCmd("get", cmdGet);
|
||||||
CONSOLE.cmdSet = consoleRegCmd("set", cmdSet);
|
CONSOLE.cmdSet = consoleRegCmd("set", cmdSet);
|
||||||
|
consoleRegCmd("echo", cmdEcho);
|
||||||
#define X(unused, command, function) \
|
consoleRegCmd("quit", cmdQuit);
|
||||||
consoleRegCmd(command, function);
|
|
||||||
#include "console/cmd/cmdlist.h"
|
|
||||||
#undef X
|
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
threadInit(&CONSOLE.thread, consoleInputThread);
|
threadInit(&CONSOLE.thread, consoleInputThread);
|
||||||
threadMutexInit(&CONSOLE.execMutex);
|
threadMutexInit(&CONSOLE.execMutex);
|
||||||
|
threadMutexInit(&CONSOLE.printMutex);
|
||||||
threadStartRequest(&CONSOLE.thread);
|
threadStartRequest(&CONSOLE.thread);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -88,6 +92,10 @@ void consolePrint(const char_t *message, ...) {
|
|||||||
int32_t len = stringFormatVA(buffer, CONSOLE_LINE_MAX, message, args);
|
int32_t len = stringFormatVA(buffer, CONSOLE_LINE_MAX, message, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
|
threadMutexLock(&CONSOLE.printMutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Move all lines back
|
// Move all lines back
|
||||||
memoryMove(
|
memoryMove(
|
||||||
CONSOLE.line[0],
|
CONSOLE.line[0],
|
||||||
@@ -101,6 +109,11 @@ void consolePrint(const char_t *message, ...) {
|
|||||||
buffer,
|
buffer,
|
||||||
len + 1
|
len + 1
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
|
threadMutexUnlock(&CONSOLE.printMutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
logDebug("%s", buffer);
|
logDebug("%s", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,11 +129,14 @@ void consoleExec(const char_t *line) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
char_t buffer[CONSOLE_LINE_MAX];
|
char_t buffer[CONSOLE_LINE_MAX];
|
||||||
|
char_t pendingPrint[CONSOLE_LINE_MAX];
|
||||||
size_t i = 0, j = 0;
|
size_t i = 0, j = 0;
|
||||||
char_t c;
|
char_t c;
|
||||||
consoleexecstate_t state = CONSOLE_EXEC_STATE_INITIAL;
|
consoleexecstate_t state = CONSOLE_EXEC_STATE_INITIAL;
|
||||||
consolecmdexec_t *exec = NULL;
|
consolecmdexec_t *exec = NULL;
|
||||||
|
|
||||||
|
pendingPrint[0] = '\0';
|
||||||
|
|
||||||
while(state != CONSOLE_EXEC_STATE_FULLY_PARSED) {
|
while(state != CONSOLE_EXEC_STATE_FULLY_PARSED) {
|
||||||
c = line[i];
|
c = line[i];
|
||||||
|
|
||||||
@@ -149,16 +165,16 @@ void consoleExec(const char_t *line) {
|
|||||||
|
|
||||||
if(c == '"') {
|
if(c == '"') {
|
||||||
// Can't handle quotes within the command.
|
// Can't handle quotes within the command.
|
||||||
consolePrint("Invalid command");
|
stringCopy(pendingPrint, "Invalid command", CONSOLE_LINE_MAX);
|
||||||
while(c != '\0' && c != ';') c = line[++i];
|
while(c != '\0' && c != ';') c = line[++i];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer[j++] = c;
|
buffer[j++] = c;
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if(j >= CONSOLE_LINE_MAX) {
|
if(j >= CONSOLE_LINE_MAX) {
|
||||||
consolePrint("Command too long");
|
stringCopy(pendingPrint, "Command too long", CONSOLE_LINE_MAX);
|
||||||
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -212,7 +228,7 @@ void consoleExec(const char_t *line) {
|
|||||||
i++;
|
i++;
|
||||||
|
|
||||||
if(j >= CONSOLE_LINE_MAX) {
|
if(j >= CONSOLE_LINE_MAX) {
|
||||||
consolePrint("Arg too long");
|
stringCopy(pendingPrint, "Arg too long", CONSOLE_LINE_MAX);
|
||||||
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -226,7 +242,7 @@ void consoleExec(const char_t *line) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(c == '\0' || c == ';') {
|
if(c == '\0' || c == ';') {
|
||||||
consolePrint("Unterminated quote");
|
stringCopy(pendingPrint, "Unterminated quote", CONSOLE_LINE_MAX);
|
||||||
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -235,7 +251,7 @@ void consoleExec(const char_t *line) {
|
|||||||
c = line[++i];
|
c = line[++i];
|
||||||
|
|
||||||
if(c == '\0' || c == ';') {
|
if(c == '\0' || c == ';') {
|
||||||
consolePrint("Unterminated quote");
|
stringCopy(pendingPrint, "Unterminated quote", CONSOLE_LINE_MAX);
|
||||||
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -245,7 +261,7 @@ void consoleExec(const char_t *line) {
|
|||||||
i++;
|
i++;
|
||||||
|
|
||||||
if(j >= CONSOLE_LINE_MAX) {
|
if(j >= CONSOLE_LINE_MAX) {
|
||||||
consolePrint("Arg too long");
|
stringCopy(pendingPrint, "Arg too long", CONSOLE_LINE_MAX);
|
||||||
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -288,33 +304,44 @@ void consoleExec(const char_t *line) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(exec->cmd == NULL) {
|
||||||
// Variable not found, is there an alias that matches?
|
// Variable not found, is there an alias that matches?
|
||||||
bool_t aliasFound = false;
|
bool_t aliasFound = false;
|
||||||
for(uint32_t k = 0; k < CONSOLE.aliasCount; k++) {
|
for(uint32_t k = 0; k < CONSOLE.aliasCount; k++) {
|
||||||
consolealias_t *alias = &CONSOLE.aliases[k];
|
consolealias_t *alias = &CONSOLE.aliases[k];
|
||||||
if(stringCompare(alias->alias, exec->command) != 0) continue;
|
if(stringCompare(alias->alias, exec->command) != 0) continue;
|
||||||
|
|
||||||
// Matching alias found, we unlock the mutex and recursively call
|
char_t aliasCmd[CONSOLE_LINE_MAX];
|
||||||
// consoleExec to handle the alias command.
|
stringCopy(aliasCmd, alias->command, CONSOLE_LINE_MAX);
|
||||||
|
|
||||||
|
// Null exec before unlocking so the unclaimed slot cannot be
|
||||||
|
// raced by another thread calling consoleExec concurrently.
|
||||||
|
exec = NULL;
|
||||||
|
state = CONSOLE_EXEC_STATE_INITIAL;
|
||||||
|
aliasFound = true;
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
threadMutexUnlock(&CONSOLE.execMutex);
|
threadMutexUnlock(&CONSOLE.execMutex);
|
||||||
#endif
|
#endif
|
||||||
consoleExec(alias->command);
|
consoleExec(aliasCmd);
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
threadMutexLock(&CONSOLE.execMutex);
|
threadMutexLock(&CONSOLE.execMutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
aliasFound = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!aliasFound && exec->cmd == NULL) {
|
if(!aliasFound) {
|
||||||
consolePrint("Command \"%s\" not found", exec->command);
|
stringFormat(
|
||||||
|
pendingPrint, CONSOLE_LINE_MAX,
|
||||||
|
"Command \"%s\" not found", exec->command
|
||||||
|
);
|
||||||
exec = NULL;
|
exec = NULL;
|
||||||
state = CONSOLE_EXEC_STATE_INITIAL;
|
state = CONSOLE_EXEC_STATE_INITIAL;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prep for next command.
|
// Prep for next command.
|
||||||
@@ -332,6 +359,8 @@ void consoleExec(const char_t *line) {
|
|||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
threadMutexUnlock(&CONSOLE.execMutex);
|
threadMutexUnlock(&CONSOLE.execMutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if(pendingPrint[0] != '\0') consolePrint("%s", pendingPrint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void consoleUpdate() {
|
void consoleUpdate() {
|
||||||
@@ -400,6 +429,7 @@ void consoleDispose(void) {
|
|||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
threadStop(&CONSOLE.thread);
|
threadStop(&CONSOLE.thread);
|
||||||
threadMutexDispose(&CONSOLE.execMutex);
|
threadMutexDispose(&CONSOLE.execMutex);
|
||||||
|
threadMutexDispose(&CONSOLE.printMutex);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,7 +438,6 @@ void consoleDispose(void) {
|
|||||||
assertNotNull(thread, "Thread cannot be NULL.");
|
assertNotNull(thread, "Thread cannot be NULL.");
|
||||||
|
|
||||||
char_t line[CONSOLE_LINE_MAX];
|
char_t line[CONSOLE_LINE_MAX];
|
||||||
size_t cap = 0;
|
|
||||||
|
|
||||||
struct pollfd pfd = {
|
struct pollfd pfd = {
|
||||||
.fd = STDIN_FILENO,
|
.fd = STDIN_FILENO,
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ typedef struct {
|
|||||||
char_t inputBuffer[CONSOLE_LINE_MAX];
|
char_t inputBuffer[CONSOLE_LINE_MAX];
|
||||||
thread_t thread;
|
thread_t thread;
|
||||||
threadmutex_t execMutex;
|
threadmutex_t execMutex;
|
||||||
|
threadmutex_t printMutex;
|
||||||
#endif
|
#endif
|
||||||
} console_t;
|
} console_t;
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ void logDebug(const char_t *message, ...) {
|
|||||||
va_start(args, message);
|
va_start(args, message);
|
||||||
vprintf(message, args);
|
vprintf(message, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void logError(const char_t *message, ...) {
|
void logError(const char_t *message, ...) {
|
||||||
|
|||||||
Reference in New Issue
Block a user