Add special variables

Update readme
This commit is contained in:
savalet
2025-05-09 17:32:59 +02:00
parent 54ebb04ac7
commit 148e738680
10 changed files with 80 additions and 31 deletions

View File

@@ -85,7 +85,7 @@ $$(NAME_$(strip $1)): $$(LIB_NAME_$(strip $1)) $$(OBJ_$(strip $1))
endef
$(eval $(call mk-profile, release, SRC, -iquote src, $(BIN_NAME)))
$(eval $(call mk-profile, release, SRC, -iquote src -g3, $(BIN_NAME)))
$(eval $(call mk-profile, debug, SRC, -iquote src -D U_DEBUG_MODE \
-fanalyzer -g3, debug))
$(eval $(call mk-profile, test, SRC, -iquote src --coverage, test))

View File

@@ -13,6 +13,7 @@
- [x] `termname`
- [x] `which`/`where`
- [x] `yes`
- [x] `expr`
- [x] pipes
- [x] redirections
@@ -33,4 +34,4 @@
- [x] parenthesis
- [x] command history (`history` btln)
- [x] heredocs
- [ ] special env vars: `$?`, `$$`, ...
- [x] special env vars: `$?`, `$$`, ...

View File

@@ -71,6 +71,8 @@ int builtins_cd_chdir(ef_t *ef, char **args, char *path)
cd_print_error();
return RETURN_FAILURE;
}
if (ef->exec_ctx->cwdcmd != nullptr)
visitor(ef->exec_ctx->cwdcmd, ef->exec_ctx);
free(ef->exec_ctx->history->last_chdir);
ef->exec_ctx->history->last_chdir = act_pwd;
set_env(ef->env, "PWD", path);

View File

@@ -5,14 +5,12 @@
** set
*/
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "common.h"
#include "env.h"
#include "exec.h"
#include "u_str.h"
@@ -30,8 +28,8 @@ void print_local(ef_t *ef)
int special_case(ef_t *ef, char **args)
{
int piv = 0;
char *key = NULL;
char *val = NULL;
char *key = nullptr;
char *val = nullptr;
if (args[1] == NULL)
return print_local(ef), RETURN_SUCCESS;
@@ -49,21 +47,34 @@ int special_case(ef_t *ef, char **args)
return RETURN_SUCCESS;
}
int builtins_set(ef_t *ef, char **args)
static
bool handle_special_variables(ef_t *ef, char **args, char *var, int i)
{
char *var = NULL;
if (strcmp(var, "precmd") == 0) {
ef->exec_ctx->precmd = strdup(args[i]);
return true;
}
if (strcmp(var, "cwdcmd") == 0) {
ef->exec_ctx->cwdcmd = strdup(args[i]);
return true;
}
return false;
}
if (my_array_len(args) < 3)
return special_case(ef, args);
static
int handle_set(ef_t *ef, char **args, char *var)
{
for (int i = 1; args[i]; i++){
if (check_local_var(args[i], args[0]))
return RETURN_FAILURE;
var = args[i];
i++;
if (handle_special_variables(ef, args, var, i))
return RETURN_SUCCESS;
if (!args[i])
return (set_local(ef->exec_ctx->local, var, NULL)
return (set_local(ef->exec_ctx->local, var, nullptr)
, RETURN_SUCCESS);
if (strcmp(args[i], "="))
if (strcmp(args[i], "=") != 0)
return RETURN_FAILURE;
i++;
if (!set_local(ef->exec_ctx->local, var, args[i]))
@@ -71,3 +82,12 @@ int builtins_set(ef_t *ef, char **args)
}
return RETURN_SUCCESS;
}
int builtins_set(ef_t *ef, char **args)
{
char *var = nullptr;
if (my_array_len(args) < 3)
return special_case(ef, args);
return handle_set(ef, args, var);
}

View File

@@ -28,6 +28,8 @@ typedef struct {
int read_fd;
int isatty;
size_t prompt_len;
char *precmd;
char *cwdcmd;
} exec_ctx_t;
size_t update_command(char **buffer,

View File

@@ -19,6 +19,10 @@ char *get_env_value(env_t *env, char const *key)
{
int key_len = u_strlen(key);
if (strcmp(key, "term") == 0)
return get_env_value(env, "TERM");
if (strcmp(key, "cwd") == 0)
return get_env_value(env, "PWD");
for (size_t i = 0; i < env->sz; i++) {
if (env->env[i] == NULL)
continue;
@@ -27,7 +31,7 @@ char *get_env_value(env_t *env, char const *key)
if (u_strcmp(env->env[i], key) == 0)
return env->env[i] + key_len + 1;
}
return NULL;
return nullptr;
}
static
@@ -87,12 +91,12 @@ static
void env_bzero(char **env, size_t sz)
{
for (size_t i = 0; i < sz; i++)
env[i] = NULL;
env[i] = nullptr;
}
bool set_env(env_t *env, char *key, char *value)
{
char *new_env = NULL;
char *new_env = nullptr;
size_t key_len = u_strlen(key);
size_t value_len = u_strlen(value);
@@ -119,7 +123,7 @@ env_t parse_env(char **env)
new_env.env = (char **)malloc(sizeof(char *) * new_env.cap);
if (!new_env.env)
return (env_t){ 0, .env = NULL };
return (env_t){ 0, .env = nullptr };
env_bzero(new_env.env, new_env.sz);
for (; *env != NULL; env++) {
if (!ensure_env_capacity(&new_env))
@@ -131,6 +135,6 @@ env_t parse_env(char **env)
}
if (!ensure_env_capacity(&new_env))
return (free((void *)new_env.env), (env_t){ 0 });
new_env.env[new_env.sz] = NULL;
new_env.env[new_env.sz] = nullptr;
return new_env;
}

View File

@@ -144,7 +144,7 @@ int launch_bin(char *full_bin_path, char **args, ef_t *ef)
if (execve(full_bin_path, args, ef->env->env) < 0) {
status = command_error(full_bin_path, args, errno);
free_env(ef->env);
exit(((free_args(args), free(ef->buffer)), status));
exit(((free_args(args)), status));
}
}
if (!(ef->flags & F_PIPE) || ef->p_i == ef->p_sz - 1)

View File

@@ -16,6 +16,7 @@
#include "repl.h"
#include "repl/key_handler.h"
#include "u_str.h"
#include "visitor.h"
#include "vt100_esc_codes.h"
const key_handler_t KEY_HANDLERS[] = {
@@ -48,23 +49,31 @@ void print_second_shell_prompt(exec_ctx_t *ec)
}
}
static
void print_prompt(env_t *env_ptr, char *hostname, exec_ctx_t *ec)
{
printf(BLUE PROMPT_HEADER GREEN "%s" RESET "@" CYAN "%s" BLUE "] "
RESET "-" BLUE " [" RESET "%s" BLUE
"] " RESET "-" BLUE " [" YELLOW "%d" BLUE
"]\n└─[" PURPLE "$" BLUE "] " RESET,
get_env_value(env_ptr, "USER"),
hostname,
get_env_value(env_ptr, "PWD"),
ec->history_command->sz);
}
void print_shell_prompt(exec_ctx_t *ec)
{
env_t *env_ptr = ec->env;
char const *ps1 = get_env_value(env_ptr, "PS1");
char hostname[64];
if (ec->precmd != nullptr)
visitor(ec->precmd, ec);
if (ps1 == nullptr) {
if (gethostname(hostname, 64) < 0)
return;
printf(BLUE PROMPT_HEADER GREEN "%s" RESET "@" CYAN "%s" BLUE "] "
RESET "-" BLUE " [" RESET "%s" BLUE
"] " RESET "-" BLUE " [" YELLOW "%d" BLUE
"]\n└─[" PURPLE "$" BLUE "] " RESET,
get_env_value(env_ptr, "USER"),
hostname,
get_env_value(env_ptr, "PWD"),
ec->history_command->sz);
print_prompt(env_ptr, hostname, ec);
ec->prompt_len = 6;
} else {
printf("%s", ps1);

View File

@@ -151,8 +151,8 @@ int shell(opt_t *opt, char **env_ptr)
his_command_t *cmd_history = init_cmd_history();
local_t local = create_local();
exec_ctx_t exec_ctx = {.env = &env, .local = &local, .opt = opt,
.read_fd = get_read_fd(opt), .history = &history,
.history_command = cmd_history, .alias = &alias, 0 };
.read_fd = get_read_fd(opt), .history = &history, .precmd = nullptr,
.history_command = cmd_history, .alias = &alias, 0, .cwdcmd = nullptr};
int shell_result;
if (exec_ctx.read_fd == -1 || (int)error_in_init(&exec_ctx))

View File

@@ -329,4 +329,15 @@ TESTS = [
],
depends_on=("CD", "ENV")
),
Test(
key="SPECIAL_VARS",
name="special variables",
cmds=[
"echo $term\n",
"echo $cwd\n",
"ncd /\n",
],
depends_on=()
),
]