Get rid of getopt, use Optparse

Well, I thought I had done this before. P for portability.
This commit is contained in:
Ivan Baravy 2023-02-02 16:25:20 +00:00
parent 987095fdef
commit 12442c72a7
10 changed files with 216 additions and 73 deletions

3
.gitignore vendored
View File

@ -46,3 +46,6 @@ colors.dtp
apps/board_hello apps/board_hello
apps/board_cycle apps/board_cycle
apps/readdir apps/readdir
apps/loader
apps/asciivju
apps/justawindow

58
apps/justawindow.asm Normal file
View File

@ -0,0 +1,58 @@
use32
org 0
db 'MENUET01'
dd 1, start, i_end, e_end, e_end, 0, 0
__DEBUG__ = 1
__DEBUG_LEVEL__ = 1
include 'proc32.inc'
include 'macros.inc'
include 'debug-fdo.inc'
EFLAGS.ID = 1 SHL 21
start:
pushfd
btr dword[esp], BSF EFLAGS.ID
popfd
mcall 68, 11
redraw:
mcall 12, 1
mcall 0, <100,200>, <100,100>, 0x34ff8888, , window_title
mcall 12, 2
still:
mcall 10
dec eax
jz redraw
dec eax
jz key
button:
mcall 17
shr eax, 8
cmp eax, 1
jz exit
jmp still
key:
mcall 2
cmp ah, 0x09 ; TAB key
jmp still
exit:
mcall -1
;include_debug_strings
window_title db 'just a window',0
i_end:
rb 0x100 ; stack
e_end:

82
apps/loader.asm Normal file
View File

@ -0,0 +1,82 @@
use32
org 0x1000000
db 'MENUET01'
dd 1, start, i_end, e_end, e_end, 0, 0
__DEBUG__ = 1
__DEBUG_LEVEL__ = 1
include 'proc32.inc'
include 'macros.inc'
include 'debug-fdo.inc'
EFLAGS.ID = 1 SHL 21
start:
pushfd
btr dword[esp], BSF EFLAGS.ID
popfd
mcall 68, 11
mcall 12, 1
mcall 0, <50,200>, <50,100>, 0x3488ffff, , window_title
mcall 12, 2
mcall 15, 1, 2, 2
mcall 15, 4, 1
mcall 15, 6
mov ecx, 0
mov edx, 0xff
mov [eax+0], cl
mov [eax+1], cl
mov [eax+2], cl
mov [eax+3], dl
mov [eax+4], dl
mov [eax+5], dl
mov [eax+6], dl
mov [eax+7], dl
mov [eax+8], dl
mov [eax+9], cl
mov [eax+10], cl
mov [eax+11], cl
mcall 15, 7, eax
mcall 15, 3
redraw:
mcall 12, 1
mcall 0, <50,200>, <50,100>, 0x3488ffff, , window_title
mcall 12, 2
still:
mcall 10
dec eax
jz redraw
dec eax
jz key
button:
mcall 17
shr eax, 8
cmp eax, 1
jz exit
jmp still
key:
mcall 2
cmp ah, 0x09 ; TAB key
jmp still
exit:
mcall -1
;include_debug_strings
window_title db 'loader',0
i_end:
rb 0x100 ; stack
e_end:

View File

@ -11,7 +11,7 @@ else
$(error your OS is not supported) $(error your OS is not supported)
endif endif
all: board_hello board_cycle readdir all: board_hello board_cycle readdir loader justawindow
%: %.asm %: %.asm
$(FASM) $< $@ $(FASM) $< $@
@ -20,4 +20,4 @@ all: board_hello board_cycle readdir
.PHONY: all clean .PHONY: all clean
clean: clean:
rm -f board_hello board_cycle readdir rm -f board_hello board_cycle readdir loader justawindow

64
shell.c
View File

@ -641,7 +641,6 @@ cmd_ramdisk_init(struct shell_ctx *ctx, int argc, char **argv) {
static void static void
cmd_disk_add(struct shell_ctx *ctx, int argc, char **argv) { cmd_disk_add(struct shell_ctx *ctx, int argc, char **argv) {
(void)ctx;
const char *usage = \ const char *usage = \
"usage: disk_add <file> <name> [option]...\n" "usage: disk_add <file> <name> [option]...\n"
" <file> absolute or relative path\n" " <file> absolute or relative path\n"
@ -654,13 +653,13 @@ cmd_disk_add(struct shell_ctx *ctx, int argc, char **argv) {
size_t cache_size = 0; size_t cache_size = 0;
int adjust_cache_size = 0; int adjust_cache_size = 0;
int opt; int opt;
optind = 1; optparse_init(&ctx->opts, argv);
const char *file_name = argv[optind++]; const char *file_name = optparse_arg(&ctx->opts);
const char *disk_name = argv[optind++]; const char *disk_name = optparse_arg(&ctx->opts);
while ((opt = getopt(argc, argv, "c:")) != -1) { while ((opt = optparse(&ctx->opts, "c:")) != -1) {
switch (opt) { switch (opt) {
case 'c': case 'c':
cache_size = strtoul(optarg, NULL, 0); cache_size = strtoul(ctx->opts.optarg, NULL, 0);
adjust_cache_size = 1; adjust_cache_size = 1;
break; break;
default: default:
@ -1056,11 +1055,12 @@ cmd_mouse_move(struct shell_ctx *ctx, int argc, char **argv) {
fputs(usage, ctx->fout); fputs(usage, ctx->fout);
return; return;
} }
int lbheld = 0, mbheld = 0, rbheld = 0, xabs = 0, yabs = 0; int lbheld = 0, mbheld = 0, rbheld = 0, xabs = 0, yabs = 0;
int32_t xmoving = 0, ymoving = 0, hscroll = 0, vscroll = 0; int32_t xmoving = 0, ymoving = 0, hscroll = 0, vscroll = 0;
int opt; int opt;
optind = 1; optparse_init(&ctx->opts, argv);
while ((opt = getopt(argc, argv, "lmrx:y:h:v:")) != -1) { while ((opt = optparse(&ctx->opts, "lmrx:y:h:v:")) != -1) {
switch (opt) { switch (opt) {
case 'l': case 'l':
lbheld = 1; lbheld = 1;
@ -1072,15 +1072,15 @@ cmd_mouse_move(struct shell_ctx *ctx, int argc, char **argv) {
rbheld = 1; rbheld = 1;
break; break;
case 'x': case 'x':
switch (*optarg++) { switch (*ctx->opts.optarg++) {
case '=': case '=':
xabs = 1; xabs = 1;
__attribute__ ((fallthrough)); __attribute__ ((fallthrough));
case '+': case '+':
xmoving = strtol(optarg, NULL, 0); xmoving = strtol(ctx->opts.optarg, NULL, 0);
break; break;
case '-': case '-':
xmoving = -strtol(optarg, NULL, 0); xmoving = -strtol(ctx->opts.optarg, NULL, 0);
break; break;
default: default:
fputs(usage, ctx->fout); fputs(usage, ctx->fout);
@ -1088,15 +1088,15 @@ cmd_mouse_move(struct shell_ctx *ctx, int argc, char **argv) {
} }
break; break;
case 'y': case 'y':
switch (*optarg++) { switch (*ctx->opts.optarg++) {
case '=': case '=':
yabs = 1; yabs = 1;
__attribute__ ((fallthrough)); __attribute__ ((fallthrough));
case '+': case '+':
ymoving = strtol(optarg, NULL, 0); ymoving = strtol(ctx->opts.optarg, NULL, 0);
break; break;
case '-': case '-':
ymoving = -strtol(optarg, NULL, 0); ymoving = -strtol(ctx->opts.optarg, NULL, 0);
break; break;
default: default:
fputs(usage, ctx->fout); fputs(usage, ctx->fout);
@ -1104,18 +1104,18 @@ cmd_mouse_move(struct shell_ctx *ctx, int argc, char **argv) {
} }
break; break;
case 'h': case 'h':
if ((optarg[0] != '+') && (optarg[0] != '-')) { if ((ctx->opts.optarg[0] != '+') && (ctx->opts.optarg[0] != '-')) {
fputs(usage, ctx->fout); fputs(usage, ctx->fout);
return; return;
} }
hscroll = strtol(optarg, NULL, 0); hscroll = strtol(ctx->opts.optarg, NULL, 0);
break; break;
case 'v': case 'v':
if ((optarg[0] != '+') && (optarg[0] != '-')) { if ((ctx->opts.optarg[0] != '+') && (ctx->opts.optarg[0] != '-')) {
fputs(usage, ctx->fout); fputs(usage, ctx->fout);
return; return;
} }
vscroll = strtol(optarg, NULL, 0); vscroll = strtol(ctx->opts.optarg, NULL, 0);
break; break;
default: default:
fputs(usage, ctx->fout); fputs(usage, ctx->fout);
@ -2438,28 +2438,28 @@ cmd_ls(struct shell_ctx *ctx, int argc, char **argv, const char *usage,
return; return;
} }
int opt; int opt;
optind = 1;
const char *optstring = (f70or80 == F70) ? "f:c:e:" : "f:c:e:p:"; const char *optstring = (f70or80 == F70) ? "f:c:e:" : "f:c:e:p:";
const char *path = "."; const char *path = ".";
uint32_t readdir_enc = DEFAULT_READDIR_ENCODING; uint32_t readdir_enc = DEFAULT_READDIR_ENCODING;
uint32_t path_enc = DEFAULT_PATH_ENCODING; uint32_t path_enc = DEFAULT_PATH_ENCODING;
uint32_t from_idx = 0, count = MAX_DIRENTS_TO_READ; uint32_t from_idx = 0, count = MAX_DIRENTS_TO_READ;
if (argc > 1 && *argv[optind] != '-') { optparse_init(&ctx->opts, argv);
path = argv[optind++]; if (argc > 1 && argv[1][0] != '-') {
path = optparse_arg(&ctx->opts);
} }
while ((opt = getopt(argc, argv, optstring)) != -1) { while ((opt = optparse(&ctx->opts, optstring)) != -1) {
switch (opt) { switch (opt) {
case 'f': case 'f':
from_idx = strtoul(optarg, NULL, 0); from_idx = strtoul(ctx->opts.optarg, NULL, 0);
break; break;
case 'c': case 'c':
count = strtoul(optarg, NULL, 0); count = strtoul(ctx->opts.optarg, NULL, 0);
break; break;
case 'e': case 'e':
readdir_enc = parse_encoding(optarg); readdir_enc = parse_encoding(ctx->opts.optarg);
break; break;
case 'p': case 'p':
path_enc = parse_encoding(optarg); path_enc = parse_encoding(ctx->opts.optarg);
break; break;
default: default:
fputs(usage, ctx->fout); fputs(usage, ctx->fout);
@ -2525,6 +2525,7 @@ cmd_stat(struct shell_ctx *ctx, int argc, char **argv, f70or80_t f70or80) {
fputs(usage, ctx->fout); fputs(usage, ctx->fout);
return; return;
} }
optparse_init(&ctx->opts, argv);
bool force_ctime = false, force_mtime = false, force_atime = false; bool force_ctime = false, force_mtime = false, force_atime = false;
f7080s5arg_t fX0 = {.sf = 5, .flags = 0}; f7080s5arg_t fX0 = {.sf = 5, .flags = 0};
f7080ret_t r; f7080ret_t r;
@ -2532,10 +2533,10 @@ cmd_stat(struct shell_ctx *ctx, int argc, char **argv, f70or80_t f70or80) {
fX0.buf = &file; fX0.buf = &file;
if (f70or80 == F70) { if (f70or80 == F70) {
fX0.u.f70.zero = 0; fX0.u.f70.zero = 0;
fX0.u.f70.path = argv[1]; fX0.u.f70.path = optparse_arg(&ctx->opts);
} else { } else {
fX0.u.f80.path_encoding = DEFAULT_PATH_ENCODING; fX0.u.f80.path_encoding = DEFAULT_PATH_ENCODING;
fX0.u.f80.path = argv[1]; fX0.u.f80.path = optparse_arg(&ctx->opts);
} }
COVERAGE_ON(); COVERAGE_ON();
umka_sys_lfn(&fX0, &r, f70or80); umka_sys_lfn(&fX0, &r, f70or80);
@ -2551,8 +2552,7 @@ cmd_stat(struct shell_ctx *ctx, int argc, char **argv, f70or80_t f70or80) {
} }
int opt; int opt;
optind = 2; // skip command and file while ((opt = optparse(&ctx->opts, "cma")) != -1) {
while ((opt = getopt(argc, argv, "cma")) != -1) {
switch (opt) { switch (opt) {
case 'c': case 'c':
force_ctime = true; force_ctime = true;
@ -3735,11 +3735,11 @@ cmd_board_get(struct shell_ctx *ctx, int argc, char **argv) {
fputs(usage, ctx->fout); fputs(usage, ctx->fout);
return; return;
} }
optparse_init(&ctx->opts, argv);
int line = 0; int line = 0;
int force_newline = 0; int force_newline = 0;
int opt; int opt;
optind = 1; while ((opt = optparse(&ctx->opts, "ln")) != -1) {
while ((opt = getopt(argc, argv, "ln")) != -1) {
switch (opt) { switch (opt) {
case 'l': case 'l':
line = 1; line = 1;

View File

@ -14,6 +14,7 @@
#include <pthread.h> #include <pthread.h>
#include "umka.h" #include "umka.h"
#include "umkaio.h" #include "umkaio.h"
#include "optparse.h"
enum shell_var_type { enum shell_var_type {
SHELL_VAR_SINT, SHELL_VAR_SINT,
@ -44,7 +45,7 @@ struct shell_ctx {
const int *running; const int *running;
pthread_cond_t cmd_done; pthread_cond_t cmd_done;
pthread_mutex_t cmd_mutex; pthread_mutex_t cmd_mutex;
struct optparse opts;
}; };
struct shell_ctx * struct shell_ctx *

View File

@ -11,7 +11,6 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <limits.h> #include <limits.h>
#include <netinet/in.h>
#define __USE_GNU #define __USE_GNU
#include <signal.h> #include <signal.h>
#include <stdatomic.h> #include <stdatomic.h>
@ -20,14 +19,9 @@
#include <unistd.h> #include <unistd.h>
#define __USE_MISC #define __USE_MISC
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#define __USE_GNU
#include <sys/uio.h>
#include <threads.h>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include "umka.h" #include "umka.h"
#include "umkart.h" #include "umkart.h"
@ -40,6 +34,8 @@
#define HIST_FILE_BASENAME ".umka_os.history" #define HIST_FILE_BASENAME ".umka_os.history"
#define THREAD_STACK_SIZE 0x100000 #define THREAD_STACK_SIZE 0x100000
#define APP_MAX_MEM_SIZE 0x1000000
#define UMKA_LDR_BASE ((void*)0x1000000)
struct umka_os_ctx { struct umka_os_ctx {
struct umka_ctx *umka; struct umka_ctx *umka;
@ -117,7 +113,7 @@ dump_procs() {
appdata_t *p_begin = kos_scheduler_current[i]; appdata_t *p_begin = kos_scheduler_current[i];
appdata_t *p = p_begin; appdata_t *p = p_begin;
do { do {
printf(" %p", (void*)p); fprintf(stderr, " %p", (void*)p);
p = p->in_schedule.next; p = p->in_schedule.next;
} while (p != p_begin); } while (p != p_begin);
putchar('\n'); putchar('\n');
@ -125,20 +121,17 @@ dump_procs() {
} }
int int
load_app_host(const char *fname, void *base) { load_app_host(const char *fname, struct app_hdr *app) {
FILE *f = fopen(fname, "r"); FILE *f = fopen(fname, "r");
if (!f) { if (!f) {
perror("Can't open app file"); fprintf(stderr, "[!] can't open app file: %s", fname);
exit(1); exit(1);
} }
fread(base, 1, 0x100000, f); fread(app, 1, APP_MAX_MEM_SIZE, f);
fclose(f); fclose(f);
for (size_t i = 0; i < 0x64; i++) { kos_thread_t start = (kos_thread_t)(app->menuet.start);
fprintf(stderr, "%2.2hx ", ((uint8_t*)base)[i]); thread_start(0, start, THREAD_STACK_SIZE);
}
fprintf(stderr, "\n");
return 0; return 0;
} }
@ -177,13 +170,13 @@ hw_int(int signo) {
umka_sti(); umka_sti();
} }
int static void *
umka_display(void *arg) { umka_display(void *arg) {
(void)arg; (void)arg;
if(SDL_Init(SDL_INIT_VIDEO) < 0) if(SDL_Init(SDL_INIT_VIDEO) < 0)
{ {
fprintf(stderr, "Failed to initialize the SDL2 library\n"); fprintf(stderr, "Failed to initialize the SDL2 library\n");
return -1; return NULL;
} }
char title[64]; char title[64];
@ -199,7 +192,7 @@ umka_display(void *arg) {
if(!window) if(!window)
{ {
fprintf(stderr, "Failed to create window\n"); fprintf(stderr, "Failed to create window\n");
return -1; return NULL;
} }
SDL_Surface *window_surface = SDL_GetWindowSurface(window); SDL_Surface *window_surface = SDL_GetWindowSurface(window);
@ -207,7 +200,7 @@ umka_display(void *arg) {
if(!window_surface) if(!window_surface)
{ {
fprintf(stderr, "Failed to get the surface from the window\n"); fprintf(stderr, "Failed to get the surface from the window\n");
return -1; return NULL;
} }
void (*copy_display)(void *); void (*copy_display)(void *);
@ -229,7 +222,7 @@ umka_display(void *arg) {
SDL_UpdateWindowSurface(window); SDL_UpdateWindowSurface(window);
sleep(1); sleep(1);
} }
return 0; return NULL;
} }
uint32_t uint32_t
@ -249,7 +242,7 @@ umka_thread_cmd_runner() {
} }
} }
static int static void *
umka_monitor(void *arg) { umka_monitor(void *arg) {
(void)arg; (void)arg;
run_test(os->shell); run_test(os->shell);
@ -371,7 +364,7 @@ main(int argc, char *argv[]) {
sa.sa_sigaction = handle_i40; sa.sa_sigaction = handle_i40;
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO | SA_RESTART; sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_RESTART;
if (sigaction(SIGSEGV, &sa, NULL) == -1) { if (sigaction(SIGSEGV, &sa, NULL) == -1) {
fprintf(stderr, "Can't install 0x40 interrupt handler!\n"); fprintf(stderr, "Can't install 0x40 interrupt handler!\n");
@ -387,12 +380,20 @@ main(int argc, char *argv[]) {
return 1; return 1;
} }
struct app_hdr *app = mmap(KOS_APP_BASE, 16*0x100000, PROT_READ | PROT_WRITE struct app_hdr *app_std = mmap(KOS_APP_BASE, APP_MAX_MEM_SIZE, PROT_READ
| PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (app == MAP_FAILED) { if (app_std == MAP_FAILED) {
perror("mmap failed"); perror("mmap app_std failed");
exit(1); exit(1);
} }
memset((void*)app_std, 0, APP_MAX_MEM_SIZE);
struct app_hdr *app_ldr = mmap(UMKA_LDR_BASE, APP_MAX_MEM_SIZE, PROT_READ
| PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (app_ldr == MAP_FAILED) {
perror("mmap app_ldr failed");
exit(1);
}
memset((void*)app_ldr, 0, APP_MAX_MEM_SIZE);
kos_boot.bpp = UMKA_DEFAULT_DISPLAY_BPP; kos_boot.bpp = UMKA_DEFAULT_DISPLAY_BPP;
kos_boot.x_res = UMKA_DEFAULT_DISPLAY_WIDTH; kos_boot.x_res = UMKA_DEFAULT_DISPLAY_WIDTH;
@ -403,8 +404,6 @@ main(int argc, char *argv[]) {
os->shell->fin = fin; os->shell->fin = fin;
umka_stack_init(); umka_stack_init();
// load_app_host("../apps/board_cycle", app);
load_app_host("../apps/readdir", app);
// load_app("/rd/1/loader"); // load_app("/rd/1/loader");
struct vnet *vnet = vnet_init(VNET_TAP); struct vnet *vnet = vnet_init(VNET_TAP);
@ -452,17 +451,18 @@ main(int argc, char *argv[]) {
thread_start(1, umka_thread_board, THREAD_STACK_SIZE); thread_start(1, umka_thread_board, THREAD_STACK_SIZE);
thread_start(1, umka_thread_cmd_runner, THREAD_STACK_SIZE); thread_start(1, umka_thread_cmd_runner, THREAD_STACK_SIZE);
kos_thread_t start = (kos_thread_t)(KOS_APP_BASE + app->menuet.start); load_app_host("../apps/loader", UMKA_LDR_BASE);
thread_start(0, start, THREAD_STACK_SIZE); // load_app_host("../apps/justawindow", KOS_APP_BASE);
load_app_host("../apps/asciivju", KOS_APP_BASE);
dump_procs(); dump_procs();
thrd_t thrd_monitor; pthread_t thread_monitor;
thrd_create(&thrd_monitor, umka_monitor, NULL); pthread_create(&thread_monitor, NULL, umka_monitor, NULL);
if (show_display) { if (show_display) {
thrd_t thrd_display; pthread_t thread_display;
thrd_create(&thrd_display, umka_display, NULL); pthread_create(&thread_display, NULL, umka_display, NULL);
} }
setitimer(ITIMER_REAL, &timeout, NULL); setitimer(ITIMER_REAL, &timeout, NULL);

View File

@ -1,4 +1,4 @@
umka_set_boot_params --bpp 32 umka_set_boot_params --bpp 32 --x_res 800 --y_res 600
umka_boot umka_boot
ramdisk_init ../img/kolibri.raw ramdisk_init ../img/kolibri.raw
set_skin /sys/DEFAULT.SKN set_skin /sys/DEFAULT.SKN

View File

@ -83,8 +83,8 @@ main(int argc, char **argv) {
int reproducible = 0; int reproducible = 0;
struct optparse options; struct optparse options;
int opt;
optparse_init(&options, argv); optparse_init(&options, argv);
int opt;
while ((opt = optparse(&options, "i:o:rc")) != -1) { while ((opt = optparse(&options, "i:o:rc")) != -1) {
switch (opt) { switch (opt) {

3
vnet.c
View File

@ -53,7 +53,7 @@ vnet_input(void *udata) {
if (plen == -1) { if (plen == -1) {
plen = 0; // we have just allocated a buffer, so we have to submit it plen = 0; // we have just allocated a buffer, so we have to submit it
} }
//if (plen != 0)
fprintf(stderr, "[vnet] read %i bytes\n", plen); fprintf(stderr, "[vnet] read %i bytes\n", plen);
for (int i = 0; i < plen; i++) { for (int i = 0; i < plen; i++) {
fprintf(stderr, " %2.2x", buf->data[i]); fprintf(stderr, " %2.2x", buf->data[i]);
@ -85,7 +85,6 @@ vnet_input_monitor(struct vnet *net) {
struct vnet * struct vnet *
vnet_init(enum vnet_type type) { vnet_init(enum vnet_type type) {
// printf("vnet_init\n");
struct vnet *vnet; struct vnet *vnet;
switch (type) { switch (type) {
case VNET_FILE: case VNET_FILE: