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 sh -c "find . -mindepth 1 ! -name '*.cpio' -print0 | ${CPIO_EXE} --null -ov -H newc > \"${INITRAMFS_CPIO_FILE}\""
|
||||
WORKING_DIRECTORY ${INITRAMFS_SRC_DIR}
|
||||
DEPENDS ${INIT_FILES} init debug
|
||||
DEPENDS ${INIT_FILES} init debug termosh
|
||||
VERBATIM
|
||||
COMMENT "Packing initramfs to cpio..."
|
||||
)
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
|
||||
### v0.5.4 (The Shell Update)
|
||||
*Focus: Interactive Userspace*
|
||||
- [ ] **Userspace Shell (`ush`)**
|
||||
- [ ] **Userspace Shell (`termosh`)**
|
||||
- Porting `ksh` logic into a standalone `.hot` binary.
|
||||
- Standard I/O abstraction (stdin/stdout) to pass keyboard input to active process.
|
||||
- [ ] **Basic Utils**
|
||||
|
||||
@@ -1,18 +1,30 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright (c) 2025 0xKarinyash
|
||||
|
||||
#include "drivers/timer.h"
|
||||
#include <io.h>
|
||||
#include <core/panic.h>
|
||||
#include <core/scheduler.h>
|
||||
#include <drivers/keyboard.h>
|
||||
#include <drivers/console.h>
|
||||
#include <drivers/timer.h>
|
||||
#include <shell/builtins.h>
|
||||
#include <syscalls/proc.h>
|
||||
#include <types.h>
|
||||
|
||||
extern task* curr_task;
|
||||
|
||||
void isr_handler_c(Registers *regs) {
|
||||
if (regs->int_no == 3) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,4 +9,5 @@ message(STATUS "Building termOS's userspace")
|
||||
|
||||
add_subdirectory(libterm)
|
||||
add_subdirectory(init)
|
||||
add_subdirectory(debug)
|
||||
add_subdirectory(debug)
|
||||
add_subdirectory(termosh)
|
||||
@@ -6,9 +6,7 @@
|
||||
#include <malloc.h>
|
||||
|
||||
int main() {
|
||||
wait(spawn("debug"));
|
||||
printf("\nStill here?\n");
|
||||
while (1) {
|
||||
printf("1");
|
||||
}
|
||||
wait(spawn("termosh")); // TODO: read .cfg and spawn what stated there
|
||||
printf("\nbaiii");
|
||||
return 0;
|
||||
}
|
||||
@@ -10,4 +10,7 @@ i32 strcmp(const char *s1, const char *s2);
|
||||
i32 strncmp(const char* s1, const char* s2, u64 n);
|
||||
char* strcpy(char* dest, const char* src);
|
||||
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>
|
||||
|
||||
static char* olds;
|
||||
|
||||
void *memset(void *ptr, int value, usize num) {
|
||||
u8 *p = (u8 *)ptr;
|
||||
while (num--) {
|
||||
@@ -74,4 +76,51 @@ u64 strlen(const char* str) {
|
||||
u64 res = 0;
|
||||
for (res = 0; str[res]; 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