wip(termosh); strspn strpbrk and strtok in string.h;
This commit is contained in:
+1
-1
@@ -42,7 +42,7 @@ if(MCOPY_EXE AND MKFS_EXE AND CPIO_EXE)
|
|||||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}
|
||||||
COMMAND sh -c "find . -mindepth 1 ! -name '*.cpio' -print0 | ${CPIO_EXE} --null -ov -H newc > \"${INITRAMFS_CPIO_FILE}\""
|
COMMAND sh -c "find . -mindepth 1 ! -name '*.cpio' -print0 | ${CPIO_EXE} --null -ov -H newc > \"${INITRAMFS_CPIO_FILE}\""
|
||||||
WORKING_DIRECTORY ${INITRAMFS_SRC_DIR}
|
WORKING_DIRECTORY ${INITRAMFS_SRC_DIR}
|
||||||
DEPENDS ${INIT_FILES} init debug
|
DEPENDS ${INIT_FILES} init debug termosh
|
||||||
VERBATIM
|
VERBATIM
|
||||||
COMMENT "Packing initramfs to cpio..."
|
COMMENT "Packing initramfs to cpio..."
|
||||||
)
|
)
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
### v0.5.4 (The Shell Update)
|
### v0.5.4 (The Shell Update)
|
||||||
*Focus: Interactive Userspace*
|
*Focus: Interactive Userspace*
|
||||||
- [ ] **Userspace Shell (`ush`)**
|
- [ ] **Userspace Shell (`termosh`)**
|
||||||
- Porting `ksh` logic into a standalone `.hot` binary.
|
- Porting `ksh` logic into a standalone `.hot` binary.
|
||||||
- Standard I/O abstraction (stdin/stdout) to pass keyboard input to active process.
|
- Standard I/O abstraction (stdin/stdout) to pass keyboard input to active process.
|
||||||
- [ ] **Basic Utils**
|
- [ ] **Basic Utils**
|
||||||
|
|||||||
@@ -1,18 +1,30 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
// Copyright (c) 2025 0xKarinyash
|
// Copyright (c) 2025 0xKarinyash
|
||||||
|
|
||||||
#include "drivers/timer.h"
|
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <core/panic.h>
|
#include <core/panic.h>
|
||||||
|
#include <core/scheduler.h>
|
||||||
#include <drivers/keyboard.h>
|
#include <drivers/keyboard.h>
|
||||||
|
#include <drivers/console.h>
|
||||||
|
#include <drivers/timer.h>
|
||||||
#include <shell/builtins.h>
|
#include <shell/builtins.h>
|
||||||
|
#include <syscalls/proc.h>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
|
extern task* curr_task;
|
||||||
|
|
||||||
void isr_handler_c(Registers *regs) {
|
void isr_handler_c(Registers *regs) {
|
||||||
if (regs->int_no == 3) {
|
if (regs->int_no == 3) {
|
||||||
return print_regs();
|
return print_regs();
|
||||||
}
|
}
|
||||||
|
if ((regs->cs & 3) != 0) {
|
||||||
|
kprintf("\n[Dewar] Process '%s' (PID %d) Segmentation Fault at %X\n",
|
||||||
|
curr_task->proc->name, curr_task->proc->pid, regs->rip);
|
||||||
|
curr_task->task_state = DEAD;
|
||||||
|
sys_exit(-1);
|
||||||
|
sched_next((u64)regs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
panic_exception(regs);
|
panic_exception(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,4 +9,5 @@ message(STATUS "Building termOS's userspace")
|
|||||||
|
|
||||||
add_subdirectory(libterm)
|
add_subdirectory(libterm)
|
||||||
add_subdirectory(init)
|
add_subdirectory(init)
|
||||||
add_subdirectory(debug)
|
add_subdirectory(debug)
|
||||||
|
add_subdirectory(termosh)
|
||||||
@@ -6,9 +6,7 @@
|
|||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
wait(spawn("debug"));
|
wait(spawn("termosh")); // TODO: read .cfg and spawn what stated there
|
||||||
printf("\nStill here?\n");
|
printf("\nbaiii");
|
||||||
while (1) {
|
return 0;
|
||||||
printf("1");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -10,4 +10,7 @@ i32 strcmp(const char *s1, const char *s2);
|
|||||||
i32 strncmp(const char* s1, const char* s2, u64 n);
|
i32 strncmp(const char* s1, const char* s2, u64 n);
|
||||||
char* strcpy(char* dest, const char* src);
|
char* strcpy(char* dest, const char* src);
|
||||||
char* strncpy(char* dest, const char* src, u64 n);
|
char* strncpy(char* dest, const char* src, u64 n);
|
||||||
u64 strlen(const char* str);
|
u64 strlen(const char* str);
|
||||||
|
u64 strspn(const char* s, const char* accept);
|
||||||
|
char* strpbrk(const char* s, const char* accept);
|
||||||
|
char* strtok(char *s, const char* delim);
|
||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
static char* olds;
|
||||||
|
|
||||||
void *memset(void *ptr, int value, usize num) {
|
void *memset(void *ptr, int value, usize num) {
|
||||||
u8 *p = (u8 *)ptr;
|
u8 *p = (u8 *)ptr;
|
||||||
while (num--) {
|
while (num--) {
|
||||||
@@ -74,4 +76,51 @@ u64 strlen(const char* str) {
|
|||||||
u64 res = 0;
|
u64 res = 0;
|
||||||
for (res = 0; str[res]; res++);
|
for (res = 0; str[res]; res++);
|
||||||
return res;
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int is_in_set(char c, const char* set) {
|
||||||
|
while (*set) {
|
||||||
|
if (*set == c) return 1;
|
||||||
|
set++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 strspn(const char* s, const char* accept) {
|
||||||
|
u64 count = 0;
|
||||||
|
while (*s && is_in_set(*s, accept)) {
|
||||||
|
count++;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* strpbrk(const char* s, const char* accept) {
|
||||||
|
while (*s) {
|
||||||
|
if (is_in_set(*s, accept)) {
|
||||||
|
return (char*)s;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
// took from https://github.com/walac/glibc/blob/master/string/strtok.c
|
||||||
|
char* strtok(char *s, const char* delim) {
|
||||||
|
char* token;
|
||||||
|
if (s == nullptr) s = olds;
|
||||||
|
s += strspn(s, delim);
|
||||||
|
if (*s == '\0') {
|
||||||
|
olds = s;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
token = s;
|
||||||
|
s = strpbrk(token, delim);
|
||||||
|
if (s == nullptr) olds = token + strlen(token);
|
||||||
|
else {
|
||||||
|
*s = '\0';
|
||||||
|
olds = s + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return token;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.20)
|
||||||
|
project(termOSh LANGUAGES C)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE TERMOSH_SOURCES "src/*.c")
|
||||||
|
|
||||||
|
add_termos_executable(termosh "${TERMOSH_SOURCES}")
|
||||||
|
target_include_directories(termosh PRIVATE
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/inc"
|
||||||
|
)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
// Copyright (c) 2026 0xKarinyash
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
void not_implemented_yet();
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
// Copyright (c) 2026 0xKarinyash
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "tokens.h"
|
||||||
|
|
||||||
|
termosh_token char2token(char* token);
|
||||||
|
int tokenize(char* buffer, char* tokens[], int max_tokens);
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
// Copyright (c) 2026 0xKarinyash
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TOKEN_EMPTY,
|
||||||
|
TOKEN_NULL,
|
||||||
|
TOKEN_ILLEGAL,
|
||||||
|
|
||||||
|
TOKEN_QUIT,
|
||||||
|
TOKEN_CLEAR,
|
||||||
|
TOKEN_HELP,
|
||||||
|
TOKEN_SPAWN,
|
||||||
|
|
||||||
|
} termosh_token;
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void not_implemented_yet() {
|
||||||
|
printf("Not implemented yet!\n");
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
// Copyright (c) 2026 0xKarinyash
|
||||||
|
|
||||||
|
#include "tokens.h"
|
||||||
|
#include "parser.h"
|
||||||
|
#include "handlers.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 512
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
while (true) {
|
||||||
|
printf("termosh_> ");
|
||||||
|
char cmdbuff[BUFFER_SIZE];
|
||||||
|
gets_s(cmdbuff, BUFFER_SIZE);
|
||||||
|
char* tokens[BUFFER_SIZE];
|
||||||
|
int tokens_count = tokenize(cmdbuff, tokens, BUFFER_SIZE);
|
||||||
|
if (tokens_count < 1) continue;
|
||||||
|
termosh_token token = char2token(tokens[0]);
|
||||||
|
switch (token) {
|
||||||
|
case TOKEN_QUIT: return 0;
|
||||||
|
case TOKEN_CLEAR: not_implemented_yet(); break;
|
||||||
|
case TOKEN_HELP: not_implemented_yet(); break;
|
||||||
|
case TOKEN_SPAWN: not_implemented_yet(); break;
|
||||||
|
default: printf("Unknown command\n"); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
// Copyright (c) 2026 0xKarinyash
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "parser.h"
|
||||||
|
#include "tokens.h"
|
||||||
|
|
||||||
|
static const char* delim = " \t\r\n";
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char* str;
|
||||||
|
termosh_token token;
|
||||||
|
} termosh_token_map;
|
||||||
|
|
||||||
|
static const termosh_token_map token_map[] = {
|
||||||
|
{"q", TOKEN_QUIT},
|
||||||
|
{"quit", TOKEN_QUIT},
|
||||||
|
{"exit", TOKEN_QUIT},
|
||||||
|
|
||||||
|
{"clear", TOKEN_CLEAR},
|
||||||
|
|
||||||
|
{"help", TOKEN_HELP},
|
||||||
|
{"spawn", TOKEN_SPAWN},
|
||||||
|
|
||||||
|
{nullptr, TOKEN_NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
termosh_token char2token(char* token) {
|
||||||
|
for (int i = 0; token_map[i].str != nullptr; i++) {
|
||||||
|
if (strcmp(token, token_map[i].str) == 0) {
|
||||||
|
return token_map[i].token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TOKEN_ILLEGAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tokenize(char* buffer, char* tokens[], int max_tokens) {
|
||||||
|
char* token = strtok(buffer, delim);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (token != nullptr && i < max_tokens) {
|
||||||
|
tokens[i] = token;
|
||||||
|
token = strtok(nullptr, delim);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user