From 9f216ffc49a564e0164c856e687beb4f6a1ce244 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Sun, 12 Apr 2026 22:05:26 +0200 Subject: [PATCH] CE Implement positional arguments --- ce/ce.c | 20 ++++++++++++++++++++ ce/interp.c | 3 +++ ce/interp.h | 10 ++++++++++ ce/parser.c | 34 +++++++++++++++++++++++++++++++++- 4 files changed, 66 insertions(+), 1 deletion(-) diff --git a/ce/ce.c b/ce/ce.c index ca99635..b896a33 100644 --- a/ce/ce.c +++ b/ce/ce.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -77,8 +78,23 @@ static bool split_lines_cb (void* ctx, const char* start, size_t len) { return true; } +static bool split_args_cb (void* ctx, const char* start, size_t len) { + (void)ctx; + + if (posvar_count >= POSVAR_MAX) + return false; + + struct posvar* posvar = &posvars[posvar_count++]; + memset (posvar, 0, sizeof (*posvar)); + + memcpy (posvar->buf, start, min (len, sizeof (posvar->buf) - 1)); + + return true; +} + void app_main (void) { char scriptpathbuf[PATH_MAX]; + char posvarsbuf[2048]; char line[1024]; memset (scriptpathbuf, 0, sizeof (scriptpathbuf)); @@ -87,6 +103,10 @@ void app_main (void) { if (has_script == ST_OK) { interactive_mode = false; + if (env_get (process_get_pgid (), "args", (void*)posvarsbuf, sizeof (posvarsbuf)) == ST_OK) { + strtokenize (posvarsbuf, ' ', NULL, &split_args_cb); + } + char volume[VOLUME_MAX]; const char* path; int ret; diff --git a/ce/interp.c b/ce/interp.c index abc70b4..3ab0306 100644 --- a/ce/interp.c +++ b/ce/interp.c @@ -30,6 +30,9 @@ static bool run = true; bool interactive_mode; +struct posvar posvars[POSVAR_MAX]; +int posvar_count = 0; + bool interp_is_running (void) { return run; } void interp_shutdown (void) { run = false; } diff --git a/ce/interp.h b/ce/interp.h index 7159ba9..3596743 100644 --- a/ce/interp.h +++ b/ce/interp.h @@ -3,8 +3,15 @@ #include "context.h" #include "parser.h" +#include #include +#define POSVAR_MAX 64 + +struct posvar { + char buf[0x80]; +}; + void execute (struct ast_node* root, struct context* context, bool run_bg); bool interp_is_running (void); @@ -13,4 +20,7 @@ void interp_shutdown (void); extern bool interactive_mode; +extern struct posvar posvars[POSVAR_MAX]; +extern int posvar_count; + #endif // _INTERP_H diff --git a/ce/parser.c b/ce/parser.c index c006c99..9c7bc66 100644 --- a/ce/parser.c +++ b/ce/parser.c @@ -5,6 +5,7 @@ #include #include #include +#include #include static struct parse_rule parse_rules[] = { @@ -162,6 +163,29 @@ void tokenize (struct list_node_link** tokens, const char* text) { if (*p == '#') return; + if (*p == '$') { + p++; + struct token* token = arena_malloc (&arena, sizeof (*token)); + memset (token, 0, sizeof (*token)); + size_t i = 0; + char numbuf[TOKEN_MAX]; + + while (*p && isdigit (*p)) { + numbuf[i++] = *p; + p++; + } + + numbuf[i] = '\0'; + uint32_t idx = str_to_uint32 (numbuf) % posvar_count; + struct posvar* posvar = &posvars[idx]; + + memcpy (token->buffer, posvar->buf, sizeof (posvar->buf)); + token->class = TOKEN_CLASS_WORD; + list_append (*tokens, &token->tokens_link); + + continue; + } + if (*p == '"') { p++; struct token* token = arena_malloc (&arena, sizeof (*token)); @@ -218,7 +242,15 @@ void tokenize (struct list_node_link** tokens, const char* text) { memset (token, 0, sizeof (*token)); size_t i = 0; - while (*p && !isspace (*p) && *p != '(' && *p != ')' && *p != ';' && *p != '>' && *p != '"') { + while (*p && + !isspace (*p) && + *p != '(' && + *p != ')' && + *p != ';' && + *p != '>' && + *p != '"' && + *p != '#' && + *p != '$') { if (i < TOKEN_MAX - 1) token->buffer[i++] = *p; p++;